Android Bluetooth 框架简读 <2>

本文简要分析了Android系统中开启蓝牙和扫描蓝牙的流程。从应用层的BluetoothSettings.java开始,通过BluetoothEnabler进入LocalBluetoothAdapter,再深入BluetoothManagerService,最后到达HAL层的bluedroid协议栈。Bluetooth工程在framework层与应用层间起桥梁作用,并管理蓝牙状态机。Bluetooth使能操作在bluedroid的bluetooth.c中执行。文章还提及LocalBluetoothProfileManager在设备UUID识别和广播注册方面的作用,蓝牙扫描流程类似。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

根据前一篇的思路大致走一遍.

先从应用层开始,Settings工程的蓝牙部分,这部分还是挺熟悉的,以前在某知名公司负责ROM开发时熟悉了.当然不同系统版本,代码可能有点不同,

设置蓝牙主界面BluetoothSettings.java,但是这里大概分析开启蓝牙流程和扫描蓝牙流程.

开启蓝牙流程:

直接进入BluetoothEnabler这个类查看.

public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        // Show toast message if Bluetooth is not allowed in airplane mode
        if (isChecked &&
                !WirelessSettings.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) {
            Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
            // Reset switch to off
            buttonView.setChecked(false);
        }

        if (mLocalAdapter != null) {
            mLocalAdapter.setBluetoothEnabled(isChecked);
        }
        mSwitch.setEnabled(false);
    }

一句:

mLocalAdapter.setBluetoothEnabled(isChecked);

找到这个点时开始点,然后看一下LocalBluetoothAdapter类

public void setBluetoothEnabled(boolean enabled) {
        boolean success = enabled
                ? mAdapter.enable()
                : mAdapter.disable();

        if (success) {
            setBluetoothStateInt(enabled
                ? BluetoothAdapter.STATE_TURNING_ON
                : BluetoothAdapter.STATE_TURNING_OFF);
        } else {
            if (Utils.V) {
                Log.v(TAG, "setBluetoothEnabled call, manager didn't return " +
                        "success for enabled: " + enabled);
            }

            syncBluetoothState();
        }
    }

注意:

boolean success = enabled
                ? mAdapter.enable()
                : mAdapter.disable();

开始对蓝牙设备进行了使能操作,打开蓝牙设备mAdapter是BluetoothAdapter的一个对象,而BluetoothAdapter类在framework里面了

public boolean enable() {
        if (isEnabled() == true){
            if (DBG) Log.d(TAG, "enable(): BT is already enabled..!");
            return true;
        }
        try {
            return mManagerService.enable();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }

然后进入BluetoothManagerService中:

mManagerService.enable();
    public boolean enable() {
        if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
            (!checkIfCallerIsForegroundUser())) {
            Log.w(TAG,"enable(): not allowed for non-active and non system user");
            return false;
        }

        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                "Need BLUETOOTH ADMIN permission");
        if (DBG) {
            Log.d(TAG,"enable():  mBluetooth =" + mBluetooth +
                    " mBinding = " + mBinding);
        }

        synchronized(mReceiver) {
            mQuietEnableExternal = false;
            mEnableExternal = true;
            // waive WRITE_SECURE_SETTINGS permission check
            long callingIdentity = Binder.clearCallingIdentity();
            persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
            Binder.restoreCallingIdentity(callingIdentity);
            sendEnableMsg(false);
        }
        return true;
    }


下面:

sendDisableMsg();
private void sendEnableMsg(boolean quietMode) {
        mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,
                             quietMode ? 1 : 0, 0));
    }


搜索一下MESSAGE_ENABLE的handler处理

case MESSAGE_ENABLE:
                    if (DBG) {
                        Log.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth);
                    }
                    mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
                    mEnable = true;
                    handleEnable(msg.arg1 == 1);
                    break;

进入handleEnable中:

//Enable bluetooth
                try {
                    if (!mQuietEnable) {
                        if(!mBluetooth.enable()) {
                            Log.e(TAG,"IBluetooth.enable() returned false");
                        }
                    }
                    else {
                        if(!mBluetooth.enableNoAutoConnect()) {
                            Log.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
                        }
                    }
                } catch (RemoteException e) {
                    Log.e(TAG,"Unable to call enable()",e);
                }


mBluetooth.enable(),这个开始进入,经过状态机的消息,一直到:

//Enable
                    boolean ret = mAdapterService.enableNative();

就到了Bluetooth工程下的jni了,com_android_bluetooth_btservice_AdapterService.cpp
static jboolean enableNative(JNIEnv* env, jobject obj) {
    ALOGV("%s:",__FUNCTION__);

    jboolean result = JNI_FALSE;
    if (!sBluetoothInterface) return result;

    int ret = sBluetoothInterface->enable();
    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
    return result;
}

继续看看sBluetoothInterface是什么:

bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
            sBluetoothInterface = btStack->get_bluetooth_interface();


一看,明显了吧bluetooth_module_t这个结构体很熟悉,到了HAL层,另外还有两个结构体,这个在hardware文件下,bluetooth.h中,真正处理是蓝牙协议栈,android 4.2开始是bluedroid协议栈,路径:

~\external\bluetooth

蓝牙使能是在bluedroid下面的bluetooth.c中:这个是根据hal层的那个结构体进行关联的

static const bt_interface_t bluetoothInterface = {
    sizeof(bt_interface_t),
    init,
    enable,
    disable,
    cleanup,
    get_adapter_properties,
    get_adapter_property,
    set_adapter_property,
    get_remote_device_properties,
    get_remote_device_property,
    set_remote_device_property,
    get_remote_service_record,
    get_remote_services,
    start_discovery,
    cancel_discovery,
    create_bond,
    remove_bond,
    cancel_bond,
    pin_reply,
    ssp_reply,
    get_profile_interface,
    dut_mode_configure,
    dut_mode_send
};

然后协议栈里面:

static int enable( void )
{
    ALOGI("enable");

    /* sanity check */
    if (interface_ready() == FALSE)
        return BT_STATUS_NOT_READY;

    return btif_enable_bluetooth();
}


接着到了Btif_core.c中:

bt_status_t btif_enable_bluetooth(void)
{
    BTIF_TRACE_DEBUG0("BTIF ENABLE BLUETOOTH");

    if (btif_core_state != BTIF_CORE_STATE_DISABLED)
    {
        ALOGD("not disabled\n");
        return BT_STATUS_DONE;
    }

    btif_core_state = BTIF_CORE_STATE_ENABLING;

    /* Create the GKI tasks and run them */
    bte_main_enable(btif_local_bd_addr.address);

    return BT_STATUS_SUCCESS;
}


至于更后面,建议参考:http://blog.youkuaiyun.com/xubin341719/article/details/40402637
这个作者刚好和我的刚好可以衔接,他基本上是从描述bluedroid协议栈的工作流程的.


从上面看,Bluetooth工程负责和framework层对接,并且负责管理蓝牙的状态机,下面与HAL层对接,可以看出Bluetooth编译出来是一个apk,但是这个apk有点牛逼.

然后在回头到settings工程,其他的一些操作基本上是应用的状态广播消息变化之类的:

synchronized void setBluetoothStateInt(int state) {
        mState = state;

        if (state == BluetoothAdapter.STATE_ON) {
            // if mProfileManager hasn't been constructed yet, it will
            // get the adapter UUIDs in its constructor when it is.
            if (mProfileManager != null) {
                mProfileManager.setBluetoothStateOn();
            }
        }
    }


在跳转一个类:LocalBluetoothProfileManager

void setBluetoothStateOn() {
        ParcelUuid[] uuids = mLocalAdapter.getUuids();
        if (uuids != null) {
            updateLocalProfiles(uuids);
        }
        mEventManager.readPairedDevices();
    }

然后先看一下:

void updateLocalProfiles(ParcelUuid[] uuids)
// A2DP
        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSource)) {
            if (mA2dpProfile == null) {
                Log.d(TAG, "Adding local A2DP profile");
                mA2dpProfile = new A2dpProfile(mContext, this);
                addProfile(mA2dpProfile, A2dpProfile.NAME,
                        BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
            }
        } else if (mA2dpProfile != null) {
            Log.w(TAG, "Warning: A2DP profile was previously added but the UUID is now missing.");
        }

        // Headset / Handsfree
        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree_AG) ||
            BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP_AG)) {
            if (mHeadsetProfile == null) {
                Log.d(TAG, "Adding local HEADSET profile");
                mHeadsetProfile = new HeadsetProfile(mContext, mLocalAdapter,
                        mDeviceManager, this);
                addProfile(mHeadsetProfile, HeadsetProfile.NAME,
                        BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
            }
        } else if (mHeadsetProfile != null) {
            Log.w(TAG, "Warning: HEADSET profile was previously added but the UUID is now missing.");
        }
....



这个地方主要蓝牙的设备UUID识别和添加蓝牙状态注册广播,后面最终还有一个注册到一个广播的.这个都在settings工程里面.


蓝牙扫描的流程也是差不多的.后面介绍从Phone 工程开始的蓝牙部分.







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值