# Android6.0 之Bluetooth Enable流程分析

来源:互联网 发布:狼人杀online for mac 编辑:程序博客网 时间:2024/05/16 23:59

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服务都起来了。

1 0
原创粉丝点击