BluetoothHeadsetClient connect用于连接HFP,流程图如下:
代码如下:
//packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothHeadsetClient.java
public final class BluetoothHeadsetClient implements BluetoothProfile, AutoCloseable {
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
final IBluetoothHeadsetClient service = getService();
final boolean defaultValue = false;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled() && isValidDevice(device)) {
try {
final SynchronousResultReceiver<Boolean> recv = SynchronousResultReceiver.get();
service.connect(device, mAttributionSource, recv);
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
} catch (RemoteException | TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
}
}
return defaultValue;
}
}
调用IBluetoothHeadsetClient的connect,IBluetoothHeadsetClient是一个接口由HeadsetClientService的内部类BluetoothHeadsetClientBinder实
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
public class HeadsetClientService extends ProfileService {
private static class BluetoothHeadsetClientBinder extends IBluetoothHeadsetClient.Stub
implements IProfileServiceBinder {
private HeadsetClientService mService;
@Override
public void connect(BluetoothDevice device, AttributionSource source,
SynchronousResultReceiver receiver) {
try {
HeadsetClientService service = getService(source);
boolean defaultValue = false;
if (service != null) {
defaultValue = service.connect(device);
}
receiver.send(defaultValue);
} catch (RuntimeException e) {
receiver.propagateException(e);
}
}
}
}
HeadsetClientService connect
调用HeadsetClientService的connect方法:
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
public class HeadsetClientService extends ProfileService {
public boolean connect(BluetoothDevice device) {
if (DBG) {
Log.d(TAG, "connect " + device);
}
if (getConnectionPolicy(device) == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
Log.w(TAG, "Connection not allowed: <" + device.getAddress()
+ "> is CONNECTION_POLICY_FORBIDDEN");
return false;
}
HeadsetClientStateMachine sm = getStateMachine(device, true);
if (sm == null) {
Log.e(TAG, "Cannot allocate SM for device " + device);
return false;
}
sm.sendMessage(HeadsetClientStateMachine.CONNECT, device);
return true;
}
}
获取HeadsetClientStateMachine对象,然后发送CONNECT消息,发送的消息会在HeadsetClientStateMachine内部类Disconnected的processMessage中处理:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
public class HeadsetClientStateMachine extends StateMachine {
private final NativeInterface mNativeInterface;
class Disconnected extends State {
@Override
public synchronized boolean processMessage(Message message) {
switch (message.what) {
case CONNECT:
BluetoothDevice device = (BluetoothDevice) message.obj;//取得BluetoothDevice对象
if (!mNativeInterface.connect(device)) { //调用NativeInterface的connect方法
// No state transition is involved, fire broadcast immediately
broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
BluetoothProfile.STATE_DISCONNECTED);
break;
}
mCurrentDevice = device;
transitionTo(mConnecting); //切换到连接中状态
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
}
}
上面方法主要处理如下:
1、调用NativeInterface的connect方法
2、切换到连接中状态
下面分别进行分析:
NativeInterface connect
调用NativeInterface的connect方法:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/NativeInterface.java
public class NativeInterface {
public boolean connect(BluetoothDevice device) {
return connectNative(getByteAddress(device));
}
}
调用connectNative方法,connectNative是Native方法,通过查表得出调用的是方法connectNative:
static bthf_client_interface_t* sBluetoothHfpClientInterface = NULL;
//packages/modules/Bluetooth/android/app/jni/com_android_bluetooth_hfpclient.cpp
static jboolean connectNative(JNIEnv* env, jobject object, jbyteArray address) {
std::shared_lock<std::shared_mutex> lock(interface_mutex);
if (!sBluetoothHfpClientInterface) return JNI_FALSE;
jbyte* addr = env->GetByteArrayElements(address, NULL);
if (!addr) {
jniThrowIOException(env, EINVAL);
return JNI_FALSE;
}
bt_status_t status = sBluetoothHfpClientInterface->connect((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed AG connection, status: %d", status);
}
env->ReleaseByteArrayElements(address, addr, 0);
return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
调用bthf_client_interface_t的connect函数,bthf_client_interface_t是个结构体,在bt_hf_client.h中定义,在bt_hf_client.cc中实现:
//packages/modules/Bluetooth/system/btif/src/bt_hf_client.cc
static bt_status_t connect(RawAddress* bd_addr) {
BTIF_TRACE_EVENT("HFP Client version is %s", btif_hf_client_version);
CHECK_BTHF_CLIENT_INIT();
return btif_queue_connect(UUID_SERVCLASS_HF_HANDSFREE, bd_addr, connect_int);
}
调用btif_queue_connect函数:
//packages/modules/Bluetooth/system/btif/src/btif_profile_queue.cc
bt_status_t btif_queue_connect(uint16_t uuid, const RawAddress* bda,
btif_connect_cb_t connect_cb) {
return do_in_jni_thread(FROM_HERE,
base::Bind(&queue_int_add, uuid, *bda, connect_cb));
}
在之后就是蓝牙协议栈相关内容,在这里就不再分析了。
HeadsetClientStateMachine Connecting enter
切换到连接中状态,状态迁移后会调用到Connecting的enter方法:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
public class HeadsetClientStateMachine extends StateMachine {
class Connecting extends State {
@Override
public void enter() {
Log.i(TAG, "Enter Connecting(" + mDevice + "): "
+ messageWhatToString(getCurrentMessage().what));
sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs);
mConnectionState = BluetoothProfile.STATE_CONNECTING;
broadcastConnectionState(BluetoothProfile.STATE_CONNECTING, mLastConnectionState);
}
}
}
在这个方法中会启动连接定时器,如果连接超时会发送CONNECT_TIMEOUT消息,然后发送广播通知注册广播的APP HeadsetClient连接状态变化。
NativeInterface onConnectionStateChanged
当蓝牙协议栈(BT Stack)处理完相关请求后,会调用NativeInterface的onConnectionStateChanged方法:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/NativeInterface.java
public class NativeInterface {
private void onConnectionStateChanged(int state, int peerFeat, int chldFeat, byte[] address) {
StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); //创建StackEvent为EVENT_TYPE_CONNECTION_STATE_CHANGED的StackEvent对象
event.valueInt = state;
event.valueInt2 = peerFeat;
event.valueInt3 = chldFeat;
event.device = getDevice(address);
// BluetoothAdapter.getDefaultAdapter().getRemoteDevice(Utils.getAddressStringFromByte
// (address));
if (DBG) {
Log.d(TAG, "Device addr " + event.device.getAddress() + " State " + state);
}
HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
if (service != null) {
service.messageFromNative(event); //调用HeadsetClientService 的messageFromNative发送StackEvent
} else {
Log.w(TAG, "Ignoring message because service not available: " + event);
}
}
}
发送EVENT_TYPE_CONNECTION_STATE_CHANGED消息,消息会在HeadsetClientService的messageFromNative中处理:
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
public class HeadsetClientService extends ProfileService {
/* Handle messages from native (JNI) to Java */
public void messageFromNative(HapClientStackEvent stackEvent) {
// Decide which event should be sent to the state machine
if (stackEvent.type == HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED) {
resendToStateMachine(stackEvent);
return;
}
}
}
调用resendToStateMachine方法:
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
public class HeadsetClientService extends ProfileService {
private void resendToStateMachine(HapClientStackEvent stackEvent) {
synchronized (mStateMachines) {
BluetoothDevice device = stackEvent.device;
HapClientStateMachine sm = mStateMachines.get(device);
if (sm == null) {
if (stackEvent.type == HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED) {
switch (stackEvent.valueInt1) {
case HapClientStackEvent.CONNECTION_STATE_CONNECTED:
case HapClientStackEvent.CONNECTION_STATE_CONNECTING:
sm = getOrCreateStateMachine(device); //获取或者创建状态机
break;
default:
break;
}
}
}
if (sm == null) {
Log.e(TAG, "Cannot process stack event: no state machine: " + stackEvent);
return;
}
sm.sendMessage(HapClientStateMachine.STACK_EVENT, stackEvent); //发送STACK_EVENT
}
}
}
发送STACK_EVENT消息,发送的消息会在HeadsetClientStateMachine的内部类Connecting的processMessage中处理:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
public class HeadsetClientStateMachine extends StateMachine {
class Connecting extends State {
public boolean processMessage(Message message) {
case STACK_EVENT:
HapClientStackEvent event = (HapClientStackEvent) message.obj;
log("Connecting: stack event: " + event);
if (!mDevice.equals(event.device)) {
Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event);
}
switch (event.type) {
case HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
processConnectionEvent(event.valueInt1);
break;
default:
Log.e(TAG, "Connecting: ignoring stack event: " + event);
break;
}
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
}
}
调用processConnectionEvent方法:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
public class HeadsetClientStateMachine extends StateMachine {
private void processConnectionEvent(int state) {
switch (state) {
case HapClientStackEvent.CONNECTION_STATE_CONNECTED:
transitionTo(mConnected); //迁移到Connected状态,这个同样会调用Connected状态类的enter方法,然后发送连接状态变更广播
break;
default:
Log.e(TAG, "Incorrect state: " + state);
break;
}
}
}
到这里BluetoothHeadsetClient的connection流程就介绍完了。