# Android6.0 之Bluetooth Enable流程分析

Android6.0 之Bluetooth Enable流程分析

最近开始分析蓝牙模块代码,特在此记录一下,本文主要是基于Android6.0 代码的蓝牙系统服务的使能流程分析,因为jni以下的流程网上有很多文章写得很清楚,故本文仅分析package和framework层的流程,涉及到的主要的类有:

  • framework/base/core/java/android/bluetooth/BluetoothAdapter.java

  • framework/base/services/core/java/com/android/server/BluetoothService.java

  • framework/base/services/java/com/android/server/SystemServer.java -

  • packages/apps/Bluetooth/src/com/android/bluetooth/adapterService.java-

  • packages/apps/Bluetooth/src/com/android/bluetooth/adapterState.java-


蓝牙Enable

Android 的蓝牙Enable 是由BluetoothAdapter 提供的,只需要调用BluetoothAdapter.enable()即可启动蓝牙,下面就开始分析这一个过程

@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
    public boolean enable() {
        int state = STATE_OFF;
        if (isEnabled() == true){
            if (DBG) Log.d(TAG, "enable(): BT is already enabled..!");
            return true;
        }
        //Use service interface to get the exact state
        if (mService != null) {
            try {
               state = mService.getState();
            } catch (RemoteException e) {Log.e(TAG, "", e);}
        }

        if (state == BluetoothAdapter.STATE_BLE_ON) {
                Log.e(TAG, "BT is in BLE_ON State");
                notifyUserAction(true);
                return true;
        }
        Log.d(TAG, ":  bt enable current package name : "+ActivityThread.currentPackageName());
        AppOpsManager appOps = (AppOpsManager)((ActivityThread.currentApplication()).getApplicationContext()).getSystemService(Context.APP_OPS_SERVICE);
        if (appOps.noteOp(AppOpsManager.OP_BLUETOOTH_ON_OFF) != AppOpsManager.MODE_ALLOWED) {
           Log.d(TAG, ": bt enable");
           return false;
        }

        try {
            if (DBG) Log.d(TAG, "enable");
            return mManagerService.enable();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }

重点关注mManagerService.enable()函数,mManagerService是IBluetoothManager类型,也就是btAdapter的一个proxy,为什么这么说呢?可以看一下getDefaultAdapter()

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

    /**
     * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance.
     */
    BluetoothAdapter(IBluetoothManager managerService) {

        if (managerService == null) {
            throw new IllegalArgumentException("bluetooth manager service is null");
        }
        try {
            mService = managerService.registerAdapter(mManagerCallback);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        mManagerService = managerService;
        mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
        mToken = new Binder();
    }

通过ServiceManager 获取了一个系统服务, 然后转换为了IBluetoothManager 接口,让mManagerService 作为了BLUETOOTH_MANAGER_SERVICE的代理。
此处顺便提一下BLUETOOTH_MANAGER_SERVICE的开启,看SystemServer.java类

mSystemServiceManager.startService(BluetoothService.class);

继续看BluetoothService.java的构造函数

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

可以看到构造函数中new了BluetoothManagerService类的实例,继续看onStart函数

public void onStart() {
        Log.d(TAG, "onStart: publishing BluetoothManagerService");
        publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, mBluetoothManagerService);
    }

至此,该服务的开启分析完毕,可以知道原来BLUETOOTH_MANAGER_SERVICE就是BluetoothManagerService类。
继续回到最初的主线,现在enable的调用到了BluetoothManagerService.java中的enable()

public boolean enable() {
        ……
        /// @}
        synchronized(mReceiver) {
            mQuietEnableExternal = false;
            mEnableExternal = true;
            // waive WRITE_SECURE_SETTINGS permission check
            sendEnableMsg(false);
        }
        if (DBG) Log.d(TAG, "enable returning");
        return true;
    }

继续看sendEnableMsg

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

此处发送Handler消息,继续看处理该消息的代码

private class BluetoothHandler extends Handler {
        public BluetoothHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            if (DBG) Log.d (TAG, "Message: " + msg.what);
            switch (msg.what) {
            ……
            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()

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

        synchronized(mConnection) {
            if (DBG) Log.d(TAG, "handleEnable: mBluetooth = " + mBluetooth +
                    ", mBinding = " + mBinding + "quietMode = " + quietMode);
            if ((mBluetooth == null) && (!mBinding)) {
                if (DBG) Log.d(TAG, "Bind AdapterService");
                //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);
                    Log.e(TAG, "Fail to bind to: " + IBluetooth.class.getName());
                } 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);
                }
            }
        }
    }

绕了一圈,最后就是调用了mBluetooth.enable(),而在 BluetoothAdapter 里面本来就有一个 mService,并且 mService就是registerAdapter() 返回的 mBluetooth!

public IBluetooth registerAdapter(IBluetoothManagerCallback callback){
        if (callback == null) {
            Log.w(TAG, "Callback is null in registerAdapter");
            return null;
        }
        Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
        msg.obj = callback;
        mHandler.sendMessage(msg);
        synchronized(mConnection) {
            return mBluetooth;
        }
    }

不过值得注意的是,BluetoothAdapter类中的mService的赋值是在这里的bindService之前的,而且其他的API的实现,都是直接用的mService,所以其实bindService,是在BluetoothManagerService.java的另一个case(MESSAGE_GET_NAME_AND_ADDRESS)中调用的,这个mBluetooth就是蓝牙APP里面的AdapterService了。

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

这里用到了StateMachine,此处不展开状态机的用法,简单的说就是一个状态机包含多个状态,在不同的状态对同一个消息由不同的处理,直接看初始状态,处理该消息的地方

public boolean processMessage(Message msg) {
            AdapterService adapterService = mAdapterService;
            if (adapterService == null) {
                errorLog("Received message in OffState after cleanup: " + msg.what);
                return false;
            }

            debugLog("Current state: OFF, message: " + msg.what);

            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();
                   break;
                   ……
            }
            return true;
        }
    }

AdapterState状态机进入mPendingCommandState,并打开mPendingCommandState.setBleTurningOn(true),值得注意的是,只有这里设置为true之后,processProfileServiceStateChanged函数中才会来发送BLE_STARTED消息,调用JNI函数enableNative函数。

private void processProfileServiceStateChanged(String serviceName, int state) {
        boolean doUpdate=false;
        boolean isBleTurningOn;
        boolean isBleTurningOff;
        boolean isTurningOn;
        boolean isTurningOff;

        synchronized (mProfileServicesState) {
            Integer prevState = mProfileServicesState.get(serviceName);
            if (prevState != null && prevState != state) {
                mProfileServicesState.put(serviceName,state);
                doUpdate=true;
            }
        }
        debugLog("onProfileServiceStateChange() serviceName=" + serviceName
                + ", state = " + state + ", doUpdate = " + doUpdate);

        if (!doUpdate) {
            return;
        }

        synchronized (mAdapterStateMachine) {
            isTurningOff = mAdapterStateMachine.isTurningOff();
            isTurningOn = mAdapterStateMachine.isTurningOn();
            isBleTurningOn = mAdapterStateMachine.isBleTurningOn();
            isBleTurningOff = mAdapterStateMachine.isBleTurningOff();
        }

        debugLog("processProfileServiceStateChanged() - serviceName=" + serviceName +
                 " isTurningOn=" + isTurningOn + " isTurningOff=" + isTurningOff +
                 " isBleTurningOn=" + isBleTurningOn + " isBleTurningOff=" + isBleTurningOff);

        if (isBleTurningOn) {
            if (serviceName.equals("com.android.bluetooth.gatt.GattService")) {
                debugLog("GattService is started");
                mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BLE_STARTED));
                return;
            }            

显然此时AdapterState处于PendingCommandState,看其processMessage函数
public boolean processMessage(Message msg) {

        boolean isTurningOn= isTurningOn();
        boolean isTurningOff = isTurningOff();
        boolean isBleTurningOn = isBleTurningOn();
        boolean isBleTurningOff = isBleTurningOff();

        AdapterService adapterService = mAdapterService;
        AdapterProperties adapterProperties = mAdapterProperties;
        if ((adapterService == null) || (adapterProperties == null)) {
            errorLog("Received message in PendingCommandState after cleanup: " + msg.what);
            return false;
        }

        debugLog("Current state: PENDING_COMMAND, message: " + msg.what);

        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);
                }
                break;               
             ……

至此,上层终于调用到了jni层,enableNative是在jni注册的native函数。继续看BleOnProcessStart

void BleOnProcessStart() {
        debugLog("BleOnProcessStart()");
        Class[] supportedProfileServices = Config.getSupportedProfiles();
        //Initialize data objects
        debugLog("supportedProfileServices.length = " + supportedProfileServices.length);
        for (int i=0; i < supportedProfileServices.length;i++) {
            debugLog("supportedProfileServices[" + i + "]: " + supportedProfileServices[i].getName());
            mProfileServicesState.put(supportedProfileServices[i].getName(),BluetoothAdapter.STATE_OFF);
        }
        mRemoteDevices = new RemoteDevices(this);
        mAdapterProperties.init(mRemoteDevices);

        debugLog("BleOnProcessStart() - Make Bond State Machine");
        mBondStateMachine = BondStateMachine.make(mPowerManager, this, mAdapterProperties, mRemoteDevices);

        mJniCallbacks.init(mBondStateMachine,mRemoteDevices);
        setAdapterService(this);
        //Start Gatt service
        setGattProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON);
    }

可以看到至此,设备支持的Profile服务都起来了。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值