蓝牙打开流程-从APP层的分析

1 蓝牙服务的启动

  蓝牙服务作为系统服务,启动是从systemserver里面启动的,systemserver里面的main方法被调用,该方法运行run方法,代码如下所示:

public static void main(String[] args) {
        new SystemServer().run();
    }
if (isEmulator) {
                Slog.i(TAG, "No Bluetooh 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 {
                Slog.i(TAG, "Bluetooth Service");
                mSystemServiceManager.startService(BluetoothService.class); // 启动蓝牙服务

bluetoothservice里面的onstart方法是将蓝牙服务注册到servicemanager,如下代码

public BluetoothService(Context context) {
        super(context);
        mBluetoothManagerService = new BluetoothManagerService(context);
        //构造BluetoothManagerService对象
    }

    @Override
    public void onStart() {
        Log.d(TAG, "onStart: publishing BluetoothManagerService");
        publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, mBluetoothManagerService);// 将蓝牙服务注册到servicemanager
    }

至此,蓝牙服务已经启动,即蓝牙服务已经被注册到servicemanager里面了,使用蓝牙服务的时候,调用getsystemservice方法获取蓝牙服务的binder引用。

2 打开蓝牙

  不管是第三方应用,还是用户从设置,systemui打开蓝牙,最终调用到BluetoothManagerService里面的enable方法

 在该函数中,会向BluetoothHandler发送MESSAGE_ENABLE消息,在BluetoothHandler中处理MESSAGE_ENABLE消息

处理

MESSAGE_ENABLE消息的方法是handleEnable,handleEnable方法的代码如下:

private void handleEnable(boolean quietMode) {
        mQuietEnable = quietMode;

        synchronized(mConnection) {
            if ((mBluetooth == null) && (!mBinding)) {
                //Start bind timeout and bind
                Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
                mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
                mConnection.setGetNameAddressOnly(false);
                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;
                }
            } else if (mBluetooth != null) {
                if (mConnection.isGetNameAddressOnly()) {
                    // if GetNameAddressOnly is set, we can clear this flag,
                    // so the service won't be unbind
                    // after name and address are saved
                    mConnection.setGetNameAddressOnly(false);
                    //Register callback object
                    try {
                        mBluetooth.registerCallback(mBluetoothCallback);
                    } catch (RemoteException re) {
                        Log.e(TAG, "Unable to register BluetoothCallback",re);
                    }
                    //Inform BluetoothAdapter instances that service is up
                    sendBluetoothServiceUpCallback();
                }

                //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);
                }
            }
        }
    }

会走入上面的第一个if分支,绑定一个服务,这个服务是AdapterService,当这个服务绑定成功后,会回调onServiceConnected方法

public void onServiceConnected(ComponentName className, IBinder service) {
            if (DBG) Log.d(TAG, "BluetoothServiceConnection: " + className.getClassName());
            Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
            // TBD if (className.getClassName().equals(IBluetooth.class.getName())) {
            if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService")) {
                msg.arg1 = SERVICE_IBLUETOOTH;
                // } else if (className.getClassName().equals(IBluetoothGatt.class.getName())) {
            } else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService")) {
                msg.arg1 = SERVICE_IBLUETOOTHGATT;
            } else {
                Log.e(TAG, "Unknown service connected: " + className.getClassName());
                return;
            }
            msg.obj = service;
            mHandler.sendMessage(msg);
        }

由于绑定的是adapterservice服务,所以会走到第二个分支,第一个分支是BLE相关的,即msg.arg1的值为1,在该回调方法中会发送一个MESSAGE_BLUETOOTH_SERVICE_CONNECTED消息,在处理MESSAGE_BLUETOOTH_SERVICE_CONNECTED消息的时候,会调用到adapterservice文件里面的enable方法。

public synchronized boolean enable(boolean quietMode) {
         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");

         debugLog("enable() - Enable called with quiet mode status =  " + mQuietmode);
         mQuietmode = quietMode;
         Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_ON);
         mAdapterStateMachine.sendMessage(m);
         return true;
     }

在该方法中,会给adapter状态机发送BLE_TURN_ON消息,看看处理BLE_TURN_ON消息的地方

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();
                   break;

这段代码实现的功能是启动GattService。当GattService服务启动完成后,也会回调onServiceConnected方法,在该方法中也会发送MESSAGE_BLUETOOTH_SERVICE_CONNECTED,这个时候的msg.arg1的值为2. 看看处理MESSAGE_BLUETOOTH_SERVICE_CONNECTED的地方,在BluetoothManagerService里面

case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
                {
                    if (DBG) Log.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);

                    IBinder service = (IBinder) msg.obj;
                    synchronized(mConnection) {
                        if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
                            mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service);
                            onBluetoothGattServiceUp();
                            break;
                        } // else must be SERVICE_IBLUETOOTH

由上面的分支可知,是满足代码中的if条件的,这个时候将调用onBluetoothGattServiceUp方法,在这个方法中会调用adapterservice的onLeServiceUp方法,该方法中会发送USER_TURN_ON消息。

public void onLeServiceUp() {
        Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON);
        mAdapterStateMachine.sendMessage(m);
    }

看看处理这个消息的地方

 switch(msg.what) {
               case USER_TURN_ON:
                   notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_ON);
                   mPendingCommandState.setTurningOn(true);
                   transitionTo(mPendingCommandState);
                   sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY);
                   adapterService.startCoreServices();
                   break;

在处理这个消息的时候,会调用adapterservice中的startCoreServices方法。

void startCoreServices()
    {
        debugLog("startCoreServices()");
        Class[] supportedProfileServices = Config.getSupportedProfiles();

        //Start profile services
        if (!mProfilesStarted && supportedProfileServices.length >0) {
            //Startup all profile services
            setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON);
        }else {
            debugLog("startCoreProfiles(): Profile Services alreay started");
            mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BREDR_STARTED));
        }
    }

在该方法中启动蓝牙的服务,
Starting service com.android.bluetooth.hfp.HeadsetService
Starting service com.android.bluetooth.a2dp.A2dpService
Starting service com.android.bluetooth.hid.HidService
Starting service com.android.bluetooth.hdp.HealthService
Starting service com.android.bluetooth.pan.PanService
Starting service com.android.bluetooth.map.BluetoothMapService
Starting service com.android.bluetooth.sap.SapService
Starting service com.android.bluetooth.opp.BluetoothOppService
Starting service com.android.bluetooth.pbap.BluetoothPbapService

你可能感兴趣的:(蓝牙打开流程-从APP层的分析)