android蓝牙模块IBluetooth与IBluetoothManager详解

在android原生蓝牙进程中,有两个类需要了解一下,在蓝牙模块经常看到这两个类的影子,分别是IBluetoothIBluetoothManager其中特别是 IBluetooth.aidl,它的作用比较重要,因此有了解熟悉它的必要,首先它们的位置在/frameworks/base/core/java/android/bluetooth/下,也就是说定义在framework.jar包下,各自的职责分别是:

IBluetooth.aidl:控制蓝牙模块,例如开启扫描/停止扫描;设置蓝牙模块对外名称;操纵远程蓝牙设备,例如向远程设备发起配对过程;
IBluetoothManager.aidl:负责接收其它模块的蓝牙交互请求;大部分能力来自 IBluetooth.aidl

其实在最开始获取BluetoothAdapter的过程中,IBluetoothManager就已经作为aidl的客户端初始化了,通过获取到的挂在系统服务里的BluetoothManagerServiceIBinder服务,然后asInterface成客户端:
代码位置:/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java

public static synchronized BluetoothAdapter getDefaultAdapter() {
    if (sAdapter == null) {
        IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
        if (b != null) {
            IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
            sAdapter = new BluetoothAdapter(managerService);
        } else {
            Log.e(TAG, "Bluetooth binder is null");
        }
    }
    return sAdapter;
}

在以下代码可以得知,ServcieManager获取的是IBinder对象,这个IBinder是一个aidl的服务端,可以看到,在蓝牙系统服务的引导过程中会将IBluetoothManagerIBinder对象公开,也就是初始化出来,让其它的应用或者服务可以调用到:

代码位置:/frameworks/base/services/core/java/com/android/server/BluetoothService.java


class BluetoothService extends SystemService {
private BluetoothManagerService mBluetoothManagerService;

public BluetoothService(Context context) {
    super(context);
    mBluetoothManagerService = new BluetoothManagerService(context);
}

@Override
public void onStart() {
}

@Override
public void onBootPhase(int phase) {
    if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
        publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE,
                mBluetoothManagerService);
    } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
        mBluetoothManagerService.handleOnBootPhase();
    }
}
}

上面讲到,BluetoothManagerService在蓝牙系统服务引导过程中被运行起来,作为IBinder服务端初始化并被系统服务集统一管理起来
代码位置:/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java

class BluetoothManagerService extends IBluetoothManager.Stub {
}

蓝牙系统服务是SystemServer这个进程启动的,这个开机启动的进程想必做android开发得或多或少都有听说过,简单来说,SystemServer就是系统用来启动原生service的入口。

Android系统在启动过程中,首先启动Zygote进程,接着由zygote进程forksystem_server进程;
SystemServer会启动我们在系统中所需要的一系列service,蓝牙服务便是在这一步骤中被启动起来的,并且在引导过程中将BluetoothManagerService初始化,将其交由系统管理。

源码位置:/frameworks/base/services/java/com/android/server/SystemServer.java

/**
 * Starts a miscellaneous grab bag of stuff that has yet to be refactored
 * and organized.
 */
private void startOtherServices() {    
    if (isEmulator) {
        Slog.i(TAG, "No Bluetooth Service (emulator)");
    } else if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
        Slog.i(TAG, "No Bluetooth Service (factory test)");
    } else if (!context.getPackageManager().hasSystemFeature
               (PackageManager.FEATURE_BLUETOOTH)) {
        Slog.i(TAG, "No Bluetooth Service (Bluetooth Hardware Not Present)");
    } else if (disableBluetooth) {
        Slog.i(TAG, "Bluetooth Service disabled by config");
    } else {
        traceBeginAndSlog("StartBluetoothService");
        mSystemServiceManager.startService(BluetoothService.class);
        traceEnd();
    }
}

现在,我们来到BluetoothManagerService,既然其开机就会被运行起来,那么我们看其何时会初始化另外一个重要的类IBluetooth,通过查阅源码发现其在以下位置被初始化,这其实是连接上了AdapterServcie后初始化的,也就是说,BluetoothManagerService在被系统蓝牙服务拉起后,会在连接上AdapterServcie这个android原生系统蓝牙进程里的服务后,初始化IBluetooth接口

源码位置:/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java

case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
{                    
    IBinder service = (IBinder) msg.obj;
    try {         
        mBinding = false;
        mBluetoothBinder = service;
        mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
    //Register callback object
    try {
        mBluetooth.registerCallback(mBluetoothCallback);
    } catch (RemoteException re) {
        Slog.e(TAG, "Unable to register BluetoothCallback",re);
    }
        //Do enable request
        try {
            if (mQuietEnable == false) {
                if (!mBluetooth.enable()) {
                    Slog.e(TAG,"IBluetooth.enable() returned false");
                }
            } else {
                if (!mBluetooth.enableNoAutoConnect()) {
                    Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
                }
            }
        } catch (RemoteException e) {
            Slog.e(TAG,"Unable to call enable()",e);
        }
    } finally {
        mBluetoothLock.writeLock().unlock();
    }
    break;
}

private class BluetoothServiceConnection implements ServiceConnection {
    public void onServiceConnected(ComponentName componentName, IBinder service) {
        String name = componentName.getClassName();
        if (DBG) Slog.d(TAG, "BluetoothServiceConnection: " + name);
        Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
        if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
            msg.arg1 = SERVICE_IBLUETOOTH;
        } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
            msg.arg1 = SERVICE_IBLUETOOTHGATT;
        } else {
            Slog.e(TAG, "Unknown service connected: " + name);
            return;
        }
        msg.obj = service;
        mHandler.sendMessage(msg);
    }

那什么时候会bind这个AdapterServcie服务呢?是在以下方法,当有enable请求过来的时候

private void handleEnable(boolean quietMode) {
    mQuietEnable = quietMode;
      
    try {
        mBluetoothLock.writeLock().lock();
        if ((mBluetooth == null) && (!mBinding)) {
            //Start bind timeout and bind
            Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
            mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
            Intent i = new Intent(IBluetooth.class.getName());
            if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
                    UserHandle.CURRENT)) {
                mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
            } else {
                mBinding = true;
            }
        }

上边这个intent初始化其实就是请求向以下这个adapterservice的绑定,这个服务运行在系统原生的蓝牙进程当中
源码位置:/packages/apps/Bluetooth/AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.android.bluetooth"
 android:sharedUserId="android.uid.bluetooth"> 
 <application
        android:name=".btservice.AdapterApp"
        android:icon="@mipmap/bt_share"
        android:persistent="false"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:usesCleartextTraffic="false"
        android:directBootAware="true"
        android:defaultToDeviceProtectedStorage="true">
        <uses-library android:name="javax.obex" />      
        <service
            android:process="@string/process"
            android:name = ".btservice.AdapterService">
            <intent-filter>
                <action android:name="android.bluetooth.IBluetooth" />
            </intent-filter>
        </service>
</manifest>

也就是bluetoothAdapter发起enable请求的时候:
源码位置:/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java

    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
   public boolean enable() {
       if (isEnabled()) {
           if (DBG) Log.d(TAG, "enable(): BT already enabled!");
           return true;
       }
       try {
           return mManagerService.enable(ActivityThread.currentPackageName());
       } catch (RemoteException e) {Log.e(TAG, "", e);}
       return false;
   }

请求转到BluetoothManagerService这里,方法发送了消息并交由handler处理

源码位置:/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java

    public boolean enable(String packageName) throws RemoteException {        

        synchronized(mReceiver) {
            mQuietEnableExternal = false;
            mEnableExternal = true;
            // waive WRITE_SECURE_SETTINGS permission check
            sendEnableMsg(false, packageName);
        }
        if (DBG) Slog.d(TAG, "enable returning");
        return true;
    }
   private void sendEnableMsg(boolean quietMode, String packageName) {
        mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,
                             quietMode ? 1 : 0, 0));
        addActiveLog(packageName, true);
    }

消息MESSAGE_ENABLE的处理:

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

                    // Use service interface to get the exact state
                    try {
                        mBluetoothLock.readLock().lock();
                        if (mBluetooth != null) {
                            int state = mBluetooth.getState();
                            if (state == BluetoothAdapter.STATE_BLE_ON) {
                                Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
                                mBluetooth.onLeServiceUp();
                                persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
                                break;
                            }
                        }
                    } catch (RemoteException e) {
                        Slog.e(TAG, "", e);
                    } finally {
                        mBluetoothLock.readLock().unlock();
                    }

                    mQuietEnable = (msg.arg1 == 1);
                    if (mBluetooth == null) {
                        handleEnable(mQuietEnable);
                    }

接着来到handleEnable处,该方法会bindaction名称为android.bluetooth.IBluetooth的服务中,也就是AdapterServcie

private void handleEnable(boolean quietMode) {
        try {
            mBluetoothLock.writeLock().lock();
            if ((mBluetooth == null) && (!mBinding)) {
                //Start bind timeout and bind
                Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
                mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
                Intent i = new Intent(IBluetooth.class.getName());
                if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
                        UserHandle.CURRENT)) {
                    mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
                } else {
                    mBinding = true;
                }
                }
        } finally {
            mBluetoothLock.writeLock().unlock();
        }
    }
    boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
        intent.setComponent(comp);
        if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
            Slog.e(TAG, "Fail to bind to: " + intent);
            return false;
        }
        return true;
    }

在连接上了AdapterServcie后,服务连接监听mConnection会回调onServiceConnected方法:
源码位置:/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java

private class BluetoothServiceConnection implements ServiceConnection {
    public void onServiceConnected(ComponentName componentName, IBinder service) {
        String name = componentName.getClassName();
        if (DBG) Slog.d(TAG, "BluetoothServiceConnection: " + name);
        Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
        if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
            msg.arg1 = SERVICE_IBLUETOOTH;
        } 
        msg.obj = service;
        mHandler.sendMessage(msg);
    }

onServiceConnected方法会发送一个消息,让mHandler处理,初始化IBluetooth并且发起enable方法:

    case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
    {
        if (DBG) Slog.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
        IBinder service = (IBinder) msg.obj;
        try {
            mBluetoothLock.writeLock().lock();
            //Remove timeout
            mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
            mBinding = false;
            mBluetoothBinder = service;
            //初始化IBluetooth
            mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
            
            //Register callback object
            try {
                mBluetooth.registerCallback(mBluetoothCallback);
            } catch (RemoteException re) {
                Slog.e(TAG, "Unable to register BluetoothCallback",re);
            }
            //Inform BluetoothAdapter instances that service is up
            sendBluetoothServiceUpCallback();
            //Do enable request 在这里调用已经初始化完毕的IBluetooth的enable方法,IBluetooth本身就是AdapterService的onBind方法里返回的AdapterServiceBinder
            try {
                if (mQuietEnable == false) {
                    if (!mBluetooth.enable()) {
                        Slog.e(TAG,"IBluetooth.enable() returned false");
                    }
                } else {
                    if (!mBluetooth.enableNoAutoConnect()) {
                        Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
                    }
                }
            } catch (RemoteException e) {
                Slog.e(TAG,"Unable to call enable()",e);
            }
        } finally {
            mBluetoothLock.writeLock().unlock();
        }
    }

也就是这一句,iBluetooth接口被初始化为客户端
mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));

总结:
android系统运行起来后,会由system_server进程运行蓝牙服务BluetoothService,而BluetoothService在引导过程中会初始化并且公布BluetoothManagerService类,一旦BluetoothAdapter接收到外部的蓝牙开启enable请求,就会转发到BluetoothManagerService里,并且BluetoothManagerServicebindAdapterService,连接成功后,就会通过aidl的方式让AdapterService去调用IBluetooth打开蓝牙,BluetoothManagerService运行在system_server进程,AdapterService运行在系统蓝牙进程,最后,在各自描述一下各个模块:

IBluetoothManager:蓝牙交互代理接口,在BluetoothAdapter里作为aidl客户端存在,负责接收蓝牙的交互请求,如enable
BluetoothManagerServiceIBluetoothManageraidl服务端,被SystemService管理
BluetoothService:运行在system_server进程,负责初始化BluetoothManagerService
IBluetooth:蓝牙的真正交互接口,在BluetoothManagerService中作为aidl客户端存在
AdapterService:android服务,持有IBluetoothaidl服务端

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
binder_open是Binder机制中的一个函数,用于打开Binder驱动并返回一个Binder状态结构体。在该函数中,会调用copy_from_user函数从用户空间获取一个struct binder_write_read结构体,并将其作为参数传递给binder_thread_write和binder_thread_read函数。\[1\] 在Binder机制的Native层实现中,binder_open函数被用于开启Binder,并将自身注册为Binder进程的上下文,然后通过调用binder_loop函数来启动Binder循环。\[2\] 在binder_loop函数中,如果收到了Binder的读写消息信息,会调用binder_parse函数进行处理。binder_parse函数会将读取到的消息进行解析,并调用相应的处理函数进行处理。\[3\] #### 引用[.reference_title] - *1* [05.Binder系统:第6课第2节_Binder系统_驱动情景分析_打印数据交互过](https://blog.csdn.net/weixin_43013761/article/details/88171380)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【Binder 机制】Native 层 Binder 机制分析 ( binder_loop | svcmgr_handler | binder.c | binder_parse )](https://blog.csdn.net/han1202012/article/details/120345228)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值