Android13 BluetoothA2dpSink disconnect流程分析

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流程就分析完了。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值