Android之Bt框架

作者: 锄禾豆 | 来源:发表于2021-05-28 19:03 被阅读0次

    源码

    7.1
    

    框架图


    启动

    1.系统服务
    SystemService
                 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 {
                    mSystemServiceManager.startService(BluetoothService.class);
                }
                
    
    com.android.server.BluetoothService
    com.android.server.BluetoothManagerService
    
    
    2.三方调用
    BluetoothManager btManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    
    过程:
    BluetoothManager 关联 BluetoothAdapter
    
    BluetoothAdapter 关联 BluetoothManagerService
    
        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;
        }
    

    案例分析: 打开蓝牙开关(BluetoothAdapter.enable())
    1.BluetoothAdapter.enable()

        public boolean enable() {
            ······
            try {
                return mManagerService.enable(ActivityThread.currentPackageName());
            } catch (RemoteException e) {Log.e(TAG, "", e);}
            return false;
        }
        
        注意:
        mManagerService的初始化为
        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;
        }
        即mManagerService为BluetoothManagerService
    

    2.BluetoothManagerService.enable

    enable --> sendEnableMsg --BluetoothHandler(MESSAGE_ENABLE)--> handleEnable
    
        private void handleEnable(boolean quietMode) {
            ······
            try {
                mBluetoothLock.writeLock().lock();
                if ((mBluetooth == null) && (!mBinding)) {
                    ······
                    Intent i = new Intent(IBluetooth.class.getName());
                    if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
                            UserHandle.CURRENT)) {//doBind就是绑定三方服务,这里就是Bluetooth.apk中的内容
                        mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
                    } else {
                        mBinding = true;
                    }
                } else if (mBluetooth != null) {
                   ······
                }
            } finally {
                mBluetoothLock.writeLock().unlock();
            }
        }
    
    注意:
    绑定三方服务成功之后,会回调mConnection.onServiceConnected
    
        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);//发送消息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);
            }
            ······
        }
    

    3.BluetoothManagerService.BluetoothHandler 处理消息 MESSAGE_BLUETOOTH_SERVICE_CONNECTED

    private class BluetoothHandler extends Handler {
            ······
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    ······
                    case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
                    {
    
                        IBinder service = (IBinder) msg.obj;
                        try {
                            mBluetoothLock.writeLock().lock();
    
                            mBinding = false;
                            mBluetoothBinder = service;
                            mBluetooth = IBluetooth.Stub.asInterface(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
                            try {
                                if (mQuietEnable == false) {
                                    if (!mBluetooth.enable()) {//调用Bluetooth.apk中的服务AdapterService
                                        Slog.e(TAG,"IBluetooth.enable() returned false");
                                    }
                                } else {
                                    ······
                                }
                            } catch (RemoteException e) {
                                Slog.e(TAG,"Unable to call enable()",e);
                            }
                        } finally {
                            mBluetoothLock.writeLock().unlock();
                        }
                        ······
                        break;
                    }
                }
    }
    

    至此,系统服务BluetoothManagerService的工作交给了Bluetooth.apk处理。整个过程涉及三方app调用系统服务,系统服务再调用三方app服务的整个过程。很典型。

    4.关注Bluetooth.apk中的调用
    1)AdapterService

    AdapterService.AdapterServiceBinder.enable --> AdapterService.enable
    
         public synchronized boolean enable(boolean quietMode) {
             ······
             mQuietmode = quietMode;
             Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_ON);//mAdapterStateMachine为状态机
             mAdapterStateMachine.sendMessage(m);
             mBluetoothStartTime = System.currentTimeMillis();
             return true;
         }
         
    这里主要涉及java和jni之间的调用关系。后面的业务涉及状态机的处理。请先熟悉StateMachine
    

    2)AdapterState

    a.初始化状态
        private AdapterState(AdapterService service, AdapterProperties adapterProperties) {
            super("BluetoothAdapterState:");
            addState(mOnState);
            addState(mBleOnState);
            addState(mOffState);
            addState(mPendingCommandState);
            mAdapterService = service;
            mAdapterProperties = adapterProperties;
            setInitialState(mOffState);//默认值为mOffState
        }
    
    b.创建对象的时候,进行了启动
    
        public static AdapterState make(AdapterService service, AdapterProperties adapterProperties) {
            Log.d(TAG, "make() - Creating AdapterState");
            AdapterState as = new AdapterState(service, adapterProperties);
            as.start();
            return as;
        }
     
    c.此时的状态为OffState
    
    “1)”发送消息AdapterState.BLE_TURN_ON,OffState处理。具体如下:
        private class OffState extends State {
            ······
            @Override
            public boolean processMessage(Message msg) {
                ······
                switch(msg.what) {
                   case BLE_TURN_ON:
                       notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_TURNING_ON);
                       mPendingCommandState.setBleTurningOn(true);
                       transitionTo(mPendingCommandState);//切换成待定状态
                       sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
                       adapterService.BleOnProcessStart();//启动蓝牙的关键,这里也涉及把BLE_START_TIMEOUT去除
                       break;
                ······
                }
            }
        }
    

    3)AdapterService.BleOnProcessStart

        void BleOnProcessStart() {
            ······
            if (getApplicationContext().getResources().getBoolean(
                    R.bool.config_bluetooth_reload_supported_profiles_when_enabled)) {
                Config.init(getApplicationContext());
            }
    
            Class[] supportedProfileServices = Config.getSupportedProfiles();//初始化配置文件服务
            //Initialize data objects
            for (int i=0; i < supportedProfileServices.length;i++) {
                mProfileServicesState.put(supportedProfileServices[i].getName(),BluetoothAdapter.STATE_OFF);
            }
            ······
            //Start Gatt service
            setGattProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON);
        }
        
        private void setGattProfileServiceState(Class[] services, int state) {
            ······
            for (int i=0; i <services.length;i++) {
                String serviceName = services[i].getName();
                String simpleName = services[i].getSimpleName();
    
                if (simpleName.equals("GattService")) {
                    Integer serviceState = mProfileServicesState.get(serviceName);
    
                    if(serviceState != null && serviceState != expectedCurrentState) {
                        debugLog("setProfileServiceState() - Unable to "
                            + (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" )
                            + " service " + serviceName
                            + ". Invalid state: " + serviceState);
                            continue;
                    }
                    debugLog("setProfileServiceState() - "
                        + (state == BluetoothAdapter.STATE_OFF ? "Stopping" : "Starting")
                        + " service " + serviceName);
    
                    mProfileServicesState.put(serviceName,pendingState);
                    Intent intent = new Intent(this,services[i]);
                    intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED);
                    intent.putExtra(BluetoothAdapter.EXTRA_STATE,state);
                    startService(intent);//启动
                    return;
                }
            }
        }
    

    4)GattService

    a.关注GattService继承关系
    GattService extends ProfileService
    ProfileService extends Service
    
    b.关注Service启动的生命周期
    
    ProfileService.onStartCommand
    
        public int onStartCommand(Intent intent, int flags, int startId) {
            ······
            if (intent == null) {
                Log.d(mName, "Restarting profile service...");
                return PROFILE_SERVICE_MODE;
            } else {
                String action = intent.getStringExtra(AdapterService.EXTRA_ACTION);
                if (AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
                    int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
                    if(state==BluetoothAdapter.STATE_OFF) {
                        Log.d(mName, "Received stop request...Stopping profile...");
                        doStop(intent);
                    } else if (state == BluetoothAdapter.STATE_ON) {
                        Log.d(mName, "Received start request. Starting profile...");
                        doStart(intent);//启动intent
                    }
                }
            }
            return PROFILE_SERVICE_MODE;
        }
        
        private void doStart(Intent intent) {
            //Start service
            if (mAdapter == null) {
                Log.e(mName, "Error starting profile. BluetoothAdapter is null");
            } else {
                if (DBG) log("start()");
                mStartError = !start();//启动
                if (!mStartError) {
                    notifyProfileServiceStateChanged(BluetoothAdapter.STATE_ON);//移除超时和正式启动
                } else {
                    Log.e(mName, "Error starting profile. BluetoothAdapter is null");
                }
            }
        }
        
    GattService.start
        protected boolean start() {
            if (DBG) Log.d(TAG, "start()");
            initializeNative();//初始化bt驱动
            ······
            return true;
        }
        
        private native void initializeNative();//native方法,也就是初始化对应的硬件参数
        
    ProfileService.notifyProfileServiceStateChanged --> AdapterService.onProfileServiceStateChanged --message--> AdapterService.processProfileServiceStateChanged
        private void processProfileServiceStateChanged(String serviceName, int state) {
            ······
            synchronized (mAdapterStateMachine) {
                isTurningOff = mAdapterStateMachine.isTurningOff();
                isTurningOn = mAdapterStateMachine.isTurningOn();
                isBleTurningOn = mAdapterStateMachine.isBleTurningOn();
                isBleTurningOff = mAdapterStateMachine.isBleTurningOff();
            }
            ······
            if (isBleTurningOn) {
                if (serviceName.equals("com.android.bluetooth.gatt.GattService")) {
                    debugLog("GattService is started");
                    mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BLE_STARTED));//状态机处理,注意此时AdapterState为mPendingCommandState
                    return;
                }
    
            } ······
        }
    

    5)AdapterState.mPendingCommandState

        private class PendingCommandState extends State {
            ······
            @Override
            public boolean processMessage(Message msg) {
                ······
                switch (msg.what) {
                    ······
                    case BLE_STARTED:
                        //Remove start timeout
                        removeMessages(BLE_START_TIMEOUT);
    
                        //Enable
                        boolean isGuest = UserManager.get(mAdapterService).isGuestUser();
                        if (!adapterService.enableNative(isGuest)) {//启动
                            errorLog("Error while turning Bluetooth on");
                            notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
                            transitionTo(mOffState);
                        } else {
                            sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY);//启动监听。注意回调的remove动作
                        }
                        break;
                    ······
                }
                ······
            }
        }
        
    AdapterService.enableNative
    native boolean enableNative(boolean startRestricted);
    

    6)com_android_bluetooth_btservice_AdapterService.cpp

    static jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) {
        ALOGV("%s:",__FUNCTION__);
    
        jboolean result = JNI_FALSE;
        if (!sBluetoothInterface) return result;
        int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0);//启动蓝牙
        result = (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE : JNI_FALSE;
        return result;
    }
    
    注意:有关hal层有什么接口,可用关注hardware/libhardware/include/hardware/bluetooth.h
    
    sBluetoothInterface的具体实现在/system/bt目录下面
    

    5.关注system/bt里面的代码实现--省略

    6.关注system/bt回调到Bluetooth.apk的情况
    1)JniCallbacks

        void stateChangeCallback(int status) {//本设备的蓝牙打开和关闭通知
            mAdapterStateMachine.stateChangeCallback(status);
        }
    

    2)AdapterState.stateChangeCallback

        void stateChangeCallback(int status) {
            if (status == AbstractionLayer.BT_STATE_OFF) {
                sendMessage(DISABLED);
    
            } else if (status == AbstractionLayer.BT_STATE_ON) {//进入。目前状态机为mPendingCommandState
                // We should have got the property change for adapter and remote devices.
                sendMessage(ENABLED_READY);
    
            } else {
                errorLog("Incorrect status in stateChangeCallback");
            }
        }
        
        private class PendingCommandState extends State {
            ······
            @Override
            public boolean processMessage(Message msg) {
                ······
                switch (msg.what) {
                    ······
                    case ENABLED_READY:
                        removeMessages(ENABLE_TIMEOUT);//移除超时
                        mPendingCommandState.setBleTurningOn(false);
                        transitionTo(mBleOnState);//切换到mBleOnState状态
                        notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_ON);//通知改变
                        break;
                    ······
                }
                ······
            }
        }
        
        private void notifyAdapterStateChange(int newState) {
            AdapterService adapterService = mAdapterService;
            AdapterProperties adapterProperties = mAdapterProperties;
            if ((adapterService == null) || (adapterProperties == null)) {
                errorLog("notifyAdapterStateChange after cleanup:" + newState);
                return;
            }
    
            int oldState = adapterProperties.getState();
            adapterProperties.setState(newState);
            infoLog("Bluetooth adapter state changed: " + oldState + "-> " + newState);
            adapterService.updateAdapterState(oldState, newState);
        }
    

    3)AdapterService.updateAdapter

         void updateAdapterState(int prevState, int newState){
            if (mCallbacks !=null) {
                int n=mCallbacks.beginBroadcast();
                debugLog("updateAdapterState() - Broadcasting state to " + n + " receivers.");
                for (int i=0; i <n;i++) {
                    try {
                        mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState,newState);
                    }  catch (RemoteException e) {
                        debugLog("updateAdapterState() - Callback #" + i + " failed ("  + e + ")");
                    }
                }
                mCallbacks.finishBroadcast();
            }
        }
        
        mCallbacks为三方调用接口registerCallback接口注册而来
    

    7.关注系统服务:BluetoothManagerService

    因为BluetoothManagerService调用bindServiceAsUser绑定,所以从binder出发:

        private class BluetoothServiceConnection implements ServiceConnection {
            public void onServiceConnected(ComponentName componentName, IBinder service) {
                Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
                ······
                mHandler.sendMessage(msg);
            }
            ······
        }
    
        private class BluetoothHandler extends Handler {
            ······
            @Override
            public void handleMessage(Message msg) {
                ······
                switch(msg.what) {
                    case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
                    mBluetooth.registerCallback(mBluetoothCallback);//将回调方法注册进AdapterService
                    ······
                }
                
            }
            ······
        }
    
        
        private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
            @Override
            public void onBluetoothStateChange(int prevState, int newState) throws RemoteException  {
                Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE,prevState,newState);
                mHandler.sendMessage(msg);//回调方法的目的:MESSAGE_BLUETOOTH_STATE_CHANGE
            }
        };
        
        private class BluetoothHandler extends Handler {
            ······
            @Override
            public void handleMessage(Message msg) {
                ······
                switch(msg.what) {
                    case MESSAGE_BLUETOOTH_STATE_CHANGE:
                    bluetoothStateChangeHandler(prevState, newState);//处理消息
                    ······
                }
                
            }
            ······
        }
        
        private void bluetoothStateChangeHandler(int prevState, int newState) {
            //关注两个广播
            ······
            sendBleStateChanged(prevState, newState);//广播1
            ······
            if (isStandardBroadcast) {
                if (prevState == BluetoothAdapter.STATE_BLE_ON) {
                    // Show prevState of BLE_ON as OFF to standard users
                    prevState = BluetoothAdapter.STATE_OFF;
                }
                Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);//广播2
                intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
                intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
            }
        }
        
        private void sendBleStateChanged(int prevState, int newState) {
            if (DBG) Slog.d(TAG,"Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) +
                " > " + BluetoothAdapter.nameForState(newState));
            // Send broadcast message to everyone else
            Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
            intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
            intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
            mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
        }
     
        总结
        蓝牙开关关注的广播有两个:
        BluetoothAdapter.ACTION_BLE_STATE_CHANGED
        BluetoothAdapter.ACTION_STATE_CHANGED
        
        过程梳理:BLE是BT的子集
        OFF > BLE_TURNING_ON > BLE_ON > TURNING_ON > ON
        ON  > TURNING_OFF    > BLE_ON > BLE_TURNING_OFF > OFF
    

    总结

    1)三方调用系统api
    2)系统api调用系统服务BluetoothManagerService
    3)系统服务调用Bluetooth.apk
    4)Bluetooth.apk调用Hal接口,最后调进system/bt
    

    参考学习

    https://source.android.com/devices/bluetooth.html
    采用方案
    
    采用ble方案
    
    1.代码查看
    getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
    
    具体实现方案参考
    https://developer.android.com/guide/topics/connectivity/bluetooth-le
    
    2.关键点
    BluetoothGatt
    
    https://www.cnblogs.com/zhchoutai/p/8866624.html
    

    补充

    BLE 
    Bluetooth Low Energy 蓝牙低功耗技术
    蓝牙4.0引入的新技术,在安卓4.3(API 18)以上为BLE的核心功能提供平台支持和API
    
    Generic Attribute Profile (GATT)
    通过BLE连接,读写属性类小数据的Profile通用规范。现在所有的BLE应用Profile都是基于GATT的。
    
    深入理解蓝牙协议相关文章
    https://blog.csdn.net/pashanhu6402/category_6560565.html
    要求
    
    1.输出蓝牙框架
    2.输出打开蓝牙的实现流程
    3.输出传输文件的实现流程
    4.输出传输数据的实现流程
    5.主动配对业务
    

    相关文章

      网友评论

        本文标题:Android之Bt框架

        本文链接:https://www.haomeiwen.com/subject/cytesltx.html