BluetoothA2dpSink的disconnect用于断开手机,代码如下:
//packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothA2dpSink .java
public final class BluetoothA2dpSink implements BluetoothProfile {
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
final IBluetoothA2dpSink 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); //调用IBluetoothA2dpSink的disconnect方法
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
} catch (RemoteException | TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
}
}
return defaultValue;
}
}
调用IBluetoothA2dpSink的disconnect方法,IBluetoothA2dpSink是一个接口,由A2dpSinkService的内部类BluetoothA2dpSinkBinder实现:
//packages/modules/Bluetooth/abdriid/app/src/com/android/bluetooth/a2dp/A2dpSinkService.java
public class A2dpSinkService extends ProfileService {
private static class A2dpSinkServiceBinder extends IBluetoothA2dpSink.Stub
implements IProfileServiceBinder {
private A2dpSinkService mService;
public boolean disconnect(BluetoothDevice device) {
if (DBG) {
StringBuilder sb = new StringBuilder();
dump(sb);
Log.d(TAG, "A2DP disconnect device: " + device
+ ", InstanceMap start state: " + sb.toString());
}
if (device == null) {
throw new IllegalArgumentException("Null device");
}
A2dpSinkStateMachine stateMachine = mDeviceStateMap.get(device);
// a state machine instance doesn't exist. maybe it is already gone?
if (stateMachine == null) {
return false;
}
int connectionState = stateMachine.getState();
if (connectionState == BluetoothProfile.STATE_DISCONNECTED
|| connectionState == BluetoothProfile.STATE_DISCONNECTING) {
return false;
}
// upon completion of disconnect, the state machine will remove itself from the available
// devices map
stateMachine.disconnect();
return true;
}
}
调用A2dpSinkStateMachine的disconnect方法:
//packages/modules/Bluetooth/abdriid/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
public class A2dpSinkStateMachine extends StateMachine {
public final void disconnect() {
sendMessage(DISCONNECT); //发送DISCONNECT消息
}
}
发送DISCONNECT消息,发送的消息在A2dpSinkStateMachine的状态类connected的processMessage中处理:
//packages/modules/Bluetooth/abdriid/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
public class A2dpSinkStateMachine extends StateMachine {
class Connected extends State {
@Override
public boolean processMessage(Message message) {
switch (message.what) {
case DISCONNECT:
transitionTo(mDisconnecting);
mNativeInterface.disconnectA2dpSink(mDevice);
return true;
case STACK_EVENT:
processStackEvent((StackEvent) message.obj);
return true;
}
return false;
}
}
}
迁移到Disconnecting状态,会调用Disconnecting的enter方法:
//packages/modules/Bluetooth/abdriid/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
public class A2dpSinkStateMachine extends StateMachine {
protected class Disconnecting extends State {
@Override
public void enter() {
if (DBG) Log.d(TAG, "Enter Disconnecting");
onConnectionStateChanged(BluetoothProfile.STATE_DISCONNECTING);
transitionTo(mDisconnected); //迁移到Disconnected方法
}
}
}
A2dpSinkNativeInterface disconnectA2dpSink
然后调用NativeInterface的disconnectA2dpSink方法:
//packages/modules/Bluetooth/abdriid/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java
public class A2dpSinkNativeInterface {
public boolean disconnectA2dpSink(BluetoothDevice device) {
return disconnectA2dpNative(getByteAddress(device));
}
}
调用disconnectA2dpNative方法,disconnectA2dpNative方法是Native方法,实现代码如下:
//packages/modules/Bluetooth/android/app/jni/com_android_bluetooth_a2dp.cpp
static const btav_sink_interface_t* sBluetoothA2dpInterface = NULL;
static jboolean disconnectA2dpNative(JNIEnv* env, jobject object,
jbyteArray address) {
ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface);
std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
if (!sBluetoothA2dpInterface) {
ALOGE("%s: Failed to get the Bluetooth A2DP Interface", __func__);
return JNI_FALSE;
}
jbyte* addr = env->GetByteArrayElements(address, nullptr);
if (!addr) {
jniThrowIOException(env, EINVAL);
return JNI_FALSE;
}
RawAddress bd_addr;
bd_addr.FromOctets(reinterpret_cast<const uint8_t*>(addr));
bt_status_t status = sBluetoothA2dpInterface->disconnect(bd_addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("%s: Failed A2DP disconnection, status: %d", __func__, status);
}
env->ReleaseByteArrayElements(address, addr, 0);
return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
调用btav_sink_interface_t的disconnect方法,,btav_sink_interface_t是一个结构体,在bt_av.h中定义,a2dp_sink.cc中实
//packages/modules/Bluetooth/system/service/a2dp_sink.cc
bool A2dpSink::Disconnect(const std::string& device_address) {
std::lock_guard<std::mutex> lock(mutex_);
RawAddress addr;
if (!RawAddress::FromString(device_address, addr)) {
LOG(ERROR) << "Invalid device address given: " << device_address;
return false;
}
bt_status_t status =
hal::BluetoothAvInterface::Get()->GetA2dpSinkHALInterface()->disconnect(
addr);
if (status != BT_STATUS_SUCCESS) {
LOG(ERROR) << "Failed to disconnect";
return false;
}
return true;
}
在之后就是蓝牙协议栈相关内容,在这里就不再分析了。
A2dpSinkNativeInterface onConnectionStateChanged
当蓝牙协议栈(BT Stack)处理完相关请求后,会调用A2dpSinkNativeInterface的onConnectionStateChanged方法:
//packages/modules/Bluetooth/abdriid/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java
public class A2dpSinkNativeInterface {
public void onConnectionStateChanged(byte[] address, int state) {
StackEvent event =
StackEvent.connectionStateChanged(getDevice(address), state);
if (DBG) {
Log.d(TAG, "onConnectionStateChanged: " + event);
}
sendMessageToService(event);
}
}
调用sendMessageToService方法:
//packages/modules/Bluetooth/abdriid/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java
public class A2dpSinkNativeInterface {
private void sendMessageToService(StackEvent event) {
A2dpSinkService service = A2dpSinkService.getA2dpSinkService();
if (service != null) {
service.messageFromNative(event);
} else {
Log.e(TAG, "Event ignored, service not available: " + event);
}
}
}
调用A2dpSinkService的messageFromNative方法:
//packages/modules/Bluetooth/abdriid/app/src/com/android/bluetooth/a2dp/A2dpSinkService.java
public class A2dpSinkService extends ProfileService {
protected void messageFromNative(StackEvent event) {
switch (event.mType) {
case StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
onConnectionStateChanged(event);
return;
case StackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED:
onAudioStateChanged(event);
return;
case StackEvent.EVENT_TYPE_AUDIO_CONFIG_CHANGED:
onAudioConfigChanged(event);
return;
default:
Log.e(TAG, "Received unknown stack event of type " + event.mType);
return;
}
}
}
调用onConnectionStateChanged方法:
//packages/modules/Bluetooth/abdriid/app/src/com/android/bluetooth/a2dp/A2dpSinkService.java
public class A2dpSinkService extends ProfileService {
private void onConnectionStateChanged(StackEvent event) {
BluetoothDevice device = event.mDevice;
if (device == null) {
return;
}
A2dpSinkStateMachine stateMachine = getOrCreateStateMachine(device); //取得状态机对象
stateMachine.sendMessage(A2dpSinkStateMachine.STACK_EVENT, event); //发送STACK_EVENT消息给状态机
}
}
发送STACK_EVENT消息给状态机,发送的消息在A2dpSinkStateMachine的状态类Disconnected的processMessage方法中处理:
//packages/modules/Bluetooth/abdriid/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
public class A2dpSinkStateMachine extends StateMachine {
class Disconnected extends State {
@Override
public boolean processMessage(Message message) {
switch (message.what) {
case STACK_EVENT:
processStackEvent((StackEvent) message.obj); //调用processStackEvent方法
return true;
}
return false;
}
void processStackEvent(StackEvent event) {
switch (event.mType) {
case StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
switch (event.mState) {
case StackEvent.CONNECTION_STATE_DISCONNECTED:
sendMessage(CLEANUP);
break;
}
}
}
}
}
发送CLEANUP消息:
public class A2dpSinkStateMachine extends StateMachine {
protected final A2dpSinkService mService;
class Disconnected extends State {
@Override
public boolean processMessage(Message message) {
switch (message.what) {
case CLEANUP:
mService.removeStateMachine(A2dpSinkStateMachine.this);
return true;
}
return false;
}
}
}
调用A2dpSinkService的removeStateMachine方法,删除状态机。
//packages/modules/Bluetooth/abdriid/app/src/com/android/bluetooth/a2dp/A2dpSinkService.java
public class A2dpSinkService extends ProfileService {
private Map<BluetoothDevice, A2dpSinkStateMachine> mDeviceStateMap =
new ConcurrentHashMap<>(1);
public void removeStateMachine(A2dpSinkStateMachine stateMachine) {
mDeviceStateMap.remove(stateMachine.getDevice());
}
}
到这里A2dpSinkService的disconnet流程就分析完了。