Android13 BluetoothHeadsetClient disconnect流程分析

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流程就介绍完了。

Android中,可以使用Bluetooth Low Energy(BLE)API扫描、连接和断开连接BLE设备。以下是一些基本步骤: 1. 获取 BluetoothAdapter 对象:使用 BluetoothManager 获取 BluetoothAdapter 对象。 ```java BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter(); ``` 2. 检查蓝牙是否已启用:使用 isEnabled() 方法检查蓝牙是否已启用。 ```java if (!bluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } ``` 3. 开始扫描:使用 startScan() 方法开始扫描BLE设备。可以使用 BluetoothLeScanner 对象进行扫描。 ```java BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner(); scanner.startScan(mScanCallback); ``` 4. 停止扫描:使用 stopScan() 方法停止扫描BLE设备。 ```java scanner.stopScan(mScanCallback); ``` 5. 连接设备:使用 BluetoothDevice 对象连接BLE设备。可以使用 connectGatt() 方法进行连接。 ```java BluetoothGatt mBluetoothGatt = bluetoothDevice.connectGatt(this, false, mGattCallback); ``` 6. 断开连接:使用 disconnect() 方法断开连接。 ```java mBluetoothGatt.disconnect(); ``` 7. 关闭 GATT 连接:使用 close() 方法关闭 GATT 连接。 ```java mBluetoothGatt.close(); ``` 以上是一些基本步骤来扫描、连接和断开连接BLE设备。具体实现还需要根据具体需求进行调整和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值