BluetoothHeadsetClient disconnect用于断开连接HFP,代码如下:
//packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothHeadsetClient.java
public final class BluetoothHeadsetClient implements BluetoothProfile, AutoCloseable {
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + 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.disconnect(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的disconnect方法,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 disconnect(BluetoothDevice device, AttributionSource source,
SynchronousResultReceiver receiver) {
try {
HeadsetClientService service = getService(source);
boolean defaultValue = false;
if (service != null) {
defaultValue = service.disconnect(device);
}
receiver.send(defaultValue);
} catch (RuntimeException e) {
receiver.propagateException(e);
}
}
}
}
HeadsetClientService disconnect
调用HeadsetClientService的disconnect方法:
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
public class HeadsetClientService extends ProfileService {
public boolean disconnect(BluetoothDevice device) {
HeadsetClientStateMachine sm = getStateMachine(device);
if (sm == null) {
Log.e(TAG, "SM does not exist for device " + device);
return false;
}
int connectionState = sm.getConnectionState(device); //取得连接状态
if (connectionState != BluetoothProfile.STATE_CONNECTED
&& connectionState != BluetoothProfile.STATE_CONNECTING) {
return false;
}
sm.sendMessage(HeadsetClientStateMachine.DISCONNECT, device);
return true;
}
}
获取HeadsetClientStateMachine对象,然后发送DISCONNECT消息,发送的消息会在HeadsetClientStateMachine内部类connected的processMessage中处理:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
public class HeadsetClientStateMachine extends StateMachine {
private final NativeInterface mNativeInterface;
class Connected extends State {
public synchronized boolean processMessage(Message message) {
switch (message.what) {
case DISCONNECT:
BluetoothDevice dev = (BluetoothDevice) message.obj;
if (!mCurrentDevice.equals(dev)) {
break;
}
if (!mNativeInterface.disconnect(dev)) {
Log.e(TAG, "disconnectNative failed for " + dev);
}
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
}
}
NativeInterface disconnect
调用NativeInterface的disconnect方法:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/NativeInterface.java
public class NativeInterface {
public boolean disconnect(BluetoothDevice device) {
return disconnectNative(getByteAddress(device));
}
}
调用disconnectNative方法,disconnectNative是Native方法,通过查表得出调用的是方法disconnectNative:
static bthf_client_interface_t* sBluetoothHfpClientInterface = NULL;
//packages/modules/Bluetooth/android/app/jni/com_android_bluetooth_hfpclient.cpp
static jboolean disconnectNative(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->disconnect((const RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed AG disconnection, status: %d", status);
}
env->ReleaseByteArrayElements(address, addr, 0);
return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
调用bthf_client_interface_t的disconnect函数,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 disconnect(const RawAddress* bd_addr) {
CHECK_BTHF_CLIENT_INIT();
btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
if (cb != NULL) {
BTA_HfClientClose(cb->handle);
return BT_STATUS_SUCCESS;
} else {
return BT_STATUS_BUSY;
}
}
在之后就是蓝牙协议栈相关内容,在这里就不再分析了。
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的内部类Connected的processMessage中处理:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
public class HeadsetClientStateMachine extends StateMachine {
class Connected extends State {
public synchronized boolean processMessage(Message message) {
switch (message.what) {
case StackEvent.STACK_EVENT:
Intent intent = null;
StackEvent event = (StackEvent) message.obj;
logD("Connected: event type: " + event.type);
switch (event.type) {
case StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
logD("Connected: Connection state changed: " + event.device
+ ": " + event.valueInt);
processConnectionEvent(event.valueInt, event.device);
break;
default:
Log.e(TAG, "Unknown stack event: " + event.type);
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 {
// in Connected state
private void processConnectionEvent(int state, BluetoothDevice device) {
switch (state) {
case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTED:
logD("Connected disconnects.");
// AG disconnects
if (mCurrentDevice.equals(device)) {
transitionTo(mDisconnected); //切换到Disconnected状态
} else {
Log.e(TAG, "Disconnected from unknown device: " + device);
}
break;
default:
Log.e(TAG, "Connection State Device: " + device + " bad state: " + state);
break;
}
}
}
}
到这里BluetoothHeadsetClient的disconnection流程就介绍完了。