Android启动之bluetooth

前一段时间我们分析了kernelbluetooth的初始化操作,从这一章起,晓东将会和大家一起正式进入到Androidbluetooth的分析。毫无疑问,我们依然需要知道在Android启动的时候,蓝牙究竟有做些什么。

         首先我们来回顾一下Android启动的一般流程,有人把它归结为4个步骤,分别为1init进程启动;2Native服务启动;3System serverAndroid服务启动;4Home启动。那么,我们来一个个看在这几个步骤中,都有哪些是和蓝牙有关的。

1init中的bluetooth

 

[html]  view plain copy
  1. #首先是创建了两个文件夹和bluetooth相关  
  2.     mkdir /data/misc/bluetoothd 0770 bluetooth bluetooth  
  3. mkdir /data/misc/bluetooth 0770 system system  
  4. #新建了一个dbus的service,dbus是用于bluez和jni层交互的  
  5. #细心的同学已经发了,他是没有disabled的,所以,会直接启动哦  
  6. #不过dbus只是一个通路而已,我们暂时并不准备去详细地分析  
  7. service dbus /system/bin/dbus-daemon --system --nofork  
  8.     class main  
  9.     socket dbus stream 660 bluetooth bluetooth  
  10.     user bluetooth  
  11.     group bluetooth net_bt_admin  
  12. #新建了bluetoothd的service,这个就是bluez了  
  13. service bluetoothd /system/bin/bluetoothd -n  
  14.     class main  
  15.     socket bluetooth stream 660 bluetooth bluetooth  
  16.     socket dbus_bluetooth stream 660 bluetooth bluetooth  
  17.     # init.rc does not yet support applying capabilities, so run as root and  
  18.     # let bluetoothd drop uid to bluetooth with the right linux capabilities  
  19.     group bluetooth net_bt_admin misc  
  20.     disabled  
  21. #这里就是各个文件的权限配置了  
  22.     chmod 666 /dev/ttyS0  
  23.     chmod 666 /proc/bluetooth/sleep/proto  
  24.     chmod 666 /sys/class/rfkill/rfkill0/state  
  25.     chmod 666 /sys/class/rfkill/rfkill0/type  
  26.     chown bluetooth bluetooth /sys/class/rfkill/rfkill0/state  
  27.     chown bluetooth bluetooth /sys/class/rfkill/rfkill0/type  
  28. #一个hciattach的service,hciattach是bluetooth的一个工具,这里可以用来启动蓝牙  
  29. #涉及到一些vendor的信息后面就写成***了  
  30. service hciattach /system/bin/logwrapper /system/bin/hciattach -n /dev/ttyS0 ***  
  31.     class main  
  32.     user bluetooth  
  33.     group bluetooth net_bt_admin  
  34.     disabled  
  35.     oneshot  

总得来说,init的过程和蓝牙相关的就是启动了dbus service,然后新建了bluetoothdhciattachservice,其它就只有一些文件和文件夹以及他们权限相关的内容修改了。

Native服务启动就和蓝牙没有什么大的关系了,我们直接去看system server中的Android服务启动了

2system server中的bluetooth

         system server会启动ServerThread,至于为什么会走到这里,应该会有无数的文章详细介绍这个吧,晓东就不献丑了。我们直接来看蓝牙相关的内容:(代码位于framework/base/services/java/com/android/server/systemserver.java

[cpp]  view plain copy
  1. class ServerThread extends Thread {  
  2.     ……  
  3.     @Override  
  4. public void run() {  
  5.   
  6. ……  
  7.             // Skip Bluetooth if we have an emulator kernel  
  8.             // TODO: Use a more reliable check to see if this product should  
  9.             // support Bluetooth - see bug 988521  
  10.             //若是模拟器,就不用bluetooth了  
  11.             if (SystemProperties.get("ro.kernel.qemu").equals("1")) {  
  12.                 Slog.i(TAG, "No Bluetooh Service (emulator)");  
  13.                 //low level的工厂测试模式,也不启动bluetooth  
  14.             } else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {  
  15.                 Slog.i(TAG, "No Bluetooth Service (factory test)");  
  16.             } else {  
  17. //上面两种都是非正常的启动,我们可以忽略  
  18.                 Slog.i(TAG, "Bluetooth Service");  
  19.                 //新建bluetoothservice,详细见2.1  
  20.                 //加入到servicemanager中,是BluetoothAdapter.BLUETOOTH_SERVICE  
  21.                 bluetooth = new BluetoothService(context);  
  22.                 ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, bluetooth);  
  23.                 //注册之后的init,详细见2.2  
  24.                 bluetooth.initAfterRegistration();  
  25.                 //新建a2dpservice,并同样加入到servicemanager中,详细见2.3  
  26.                 bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);  
  27.                 ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,  
  28.                                           bluetoothA2dp);  
  29.                 //a2dp的init  
  30.                 bluetooth.initAfterA2dpRegistration();  
  31.                 //得到是否是飞行模式  
  32.                 int airplaneModeOn = Settings.System.getInt(mContentResolver,  
  33.                         Settings.System.AIRPLANE_MODE_ON, 0);  
  34.                 //看bluetooth在上次关闭的时候是否on的  
  35.                 int bluetoothOn = Settings.Secure.getInt(mContentResolver,  
  36.                     Settings.Secure.BLUETOOTH_ON, 0);  
  37.                     //若是非飞行模式,上次关闭前是打开,则使能bt  
  38.                     //使能bt的过程这篇文章就不介绍了,后面会另开一篇介绍  
  39.                 if (airplaneModeOn == 0 && bluetoothOn != 0) {  
  40.                     bluetooth.enable();  
  41.                 }  
  42.             }  

2.1 bluetoothservice的构造

bluetoothservice可以说是bluetooth的一个核心组成了,很多初始化都是由它这里发起的,我们来详细阅读一下:(代码位于/framework/base/core/java/android/server/bluetoothservice.java

[cpp]  view plain copy
  1.   public BluetoothService(Context context) {  
  2.         mContext = context;  
  3.   
  4.         // Need to do this in place of:  
  5.         // mBatteryStats = BatteryStatsService.getService();  
  6.         // Since we can not import BatteryStatsService from here. This class really needs to be  
  7.         // moved to java/services/com/android/server/  
  8.         //得到battery的状态  
  9.         mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));  
  10.         //是否是bt wifi 共存  
  11.         if (SystemProperties.get("ro.btwifi.coexist""true").equals("false")) {  
  12.             supportBtWifiCoexit = false;  
  13.         }  
  14.             //jni层的nativedata的一些初始化。最主要的是检查一下dbus是否能够用  
  15.             //这里就不详细介绍了,很简单,代码位于frameworks/base/core/jni/android_server_bluetoothservice.cpp中  
  16.         initializeNativeDataNative();  
  17.             //检查bt是否已经enable了,理论是不应该enable的  
  18.         if (isEnabledNative() == 1) {  
  19.             Log.w(TAG, "Bluetooth daemons already running - runtime restart? ");  
  20.             disableNative();  
  21.         }  
  22.             //这个是用来表示配对的一些状态的  
  23.             //主要是注册一个BluetoothDevice.ACTION_PAIRING_REQUEST的receiver,这样在有pair的请求的时候,他会把pair的device加入到mPairingRequestRcvd列表中  
  24.         mBondState = new BluetoothBondState(context, this);  
  25. //主要就是建了一个mPropertiesMap的hash表,保存adapter的properties        mAdapterProperties = new BluetoothAdapterProperties(context, this);  
  26. //新建了一个mPropertiesMap的hash表,用来保存device的properties  
  27.         mDeviceProperties = new BluetoothDeviceProperties(this);  
  28.   
  29.        //新建一个deviceservice channel的hash表,还有别的hash表的建立,等用到的时候再一一详细介绍  
  30. mDeviceServiceChannelCache = new HashMap<String, Map<ParcelUuid, Integer>>();  
  31.         mDeviceOobData = new HashMap<String, Pair<byte[], byte[]>>();  
  32.         mUuidIntentTracker = new ArrayList<String>();  
  33.         mUuidCallbackTracker = new HashMap<RemoteService, IBluetoothCallback>();  
  34.         mServiceRecordToPid = new HashMap<Integer, ServiceRecordClient>();  
  35.         mDeviceProfileState = new HashMap<String, BluetoothDeviceProfileState>();  
  36. //初始化两个profiles的状态机。BluetoothProfileState是用来统一管理profile的状态的,这里注册了A2DP和HFP两个profile  
  37.         mA2dpProfileState = new BluetoothProfileState(mContext, BluetoothProfileState.A2DP);  
  38.         mHfpProfileState = new BluetoothProfileState(mContext, BluetoothProfileState.HFP);  
  39.             //启动这两个状态机,开始接收各种message  
  40.         mHfpProfileState.start();  
  41.         mA2dpProfileState.start();  
  42.   
  43.         mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);  
  44.         Intent intent = new Intent(DISCOVERABLE_ALARM);  
  45.         mPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);  
  46.   
  47.         IntentFilter filter = new IntentFilter();  
  48. //就是监听ACTION_AIRPLANE_MODE_CHANGED  
  49.         registerForAirplaneMode(filter);  
  50. //加入DISCOVERABLE_ALARM,ACTION_DOCK_EVENT,ACTION_BOOT_COMPLETED的监听  
  51.         filter.addAction(DISCOVERABLE_ALARM);  
  52.         filter.addAction(Intent.ACTION_DOCK_EVENT);  
  53. //这里说明一下ACTION_BOOT_COMPLETED的处理,就是置一个mBootCompleted = true;所以,就不另外特别说明了  
  54.         filter.addAction(Intent.ACTION_BOOT_COMPLETED);  
  55.         mContext.registerReceiver(mReceiver, filter);  
  56. //构造几个profile的处理,有hid,pan和health,没有什么好说的  
  57.         mBluetoothInputProfileHandler = BluetoothInputProfileHandler.getInstance(mContext, this);  
  58.         mBluetoothPanProfileHandler = BluetoothPanProfileHandler.getInstance(mContext, this);  
  59.         mBluetoothHealthProfileHandler = BluetoothHealthProfileHandler.getInstance(mContext, this);  
  60. //再新建两个hash表  
  61.         mIncomingConnections = new HashMap<String, Pair<Integer, String>>();  
  62.         mProfileConnectionState = new HashMap<Integer, Pair<Integer, Integer>>();  
  63. }  

2.2initAfterRegistration

这个函数是用来在注册之后进行初始化的,所以,可以说是bluetoothservice中被调用的第一个函数了,我们来看看它做了一些什么:

[cpp]  view plain copy
  1. public synchronized void initAfterRegistration() {  
  2. /新建了一个bluetoothadapter,这很重要,adapter和bluetoothservice是绑定的,后期上层ui都是同adapter那边来找到bluetoothservice的  
  3.        mAdapter = BluetoothAdapter.getDefaultAdapter();  
  4. /新建bluetoothadapter的状态机,后面我会另外开一篇文章来详细介绍状态机  
  5.        mBluetoothState = new BluetoothAdapterStateMachine(mContext, this, mAdapter);  
  6.         //start状态机  
  7.        mBluetoothState.start();  
  8.         //看是否支持qucik switch,若是支持,我们会在开机的时候就默认为hot状态  
  9.         //这里就是4.0和2.3中最大的不同,就是其实默认支持quick switch的情况下,蓝牙是打开的,只是没有显示在ui界面上而已。关于这里,我会另开一篇文章来介绍  
  10.        if (mContext.getResources().getBoolean  
  11.            (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {  
  12.            mBluetoothState.sendMessage(BluetoothAdapterStateMachine.TURN_HOT);  
  13.        }  
  14.         //得到bluetooth的eventloop,eventloop在adapterstatemachine构造的时候创建的,这个很重要,不过我们也放到另外一篇文章中去详细介绍  
  15.        mEventLoop = mBluetoothState.getBluetoothEventLoop();  
  16.    }  

2.3 BluetoothA2dpService

这个是a2dp service的构造

[cpp]  view plain copy
  1.  public BluetoothA2dpService(Context context, BluetoothService bluetoothService) {  
  2.        mContext = context;  
  3. //得到audioservice  
  4.        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);  
  5. //和bluetoothservice关联  
  6.        mBluetoothService = bluetoothService;  
  7.        if (mBluetoothService == null) {  
  8.            throw new RuntimeException("Platform does not support Bluetooth");  
  9.        }  
  10. /和bluetoothservice类似,就是初始化native的data和检查dbus  
  11.        if (!initNative()) {  
  12.            throw new RuntimeException("Could not init BluetoothA2dpService");  
  13.        }  
  14.   
  15.        mAdapter = BluetoothAdapter.getDefaultAdapter();  
  16. //几个action的处理  
  17.        mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);  
  18.        mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);  
  19.        mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);  
  20.        mIntentFilter.addAction(AudioManager.VOLUME_CHANGED_ACTION);  
  21.        mContext.registerReceiver(mReceiver, mIntentFilter);  
  22.   
  23.        mAudioDevices = new HashMap<BluetoothDevice, Integer>();  
  24. /看bluetooth是否on  
  25.        if (mBluetoothService.isEnabled())  
  26.            onBluetoothEnable();  
  27.        mTargetA2dpState = -1;  
  28. /使得bluetoothservice那边能找到a2dpservice  
  29.        mBluetoothService.setA2dpService(this);  
  30.    }  

至此,android启动时,bluetooth的一些操作就已经都比较明了了。在init过程中:“init的过程和蓝牙相关的就是启动了dbus service,然后新建了bluetoothdhciattachservice,其它就只有一些文件和文件夹以及他们权限相关的内容修改了。”

system service过程中,启动了bluetooth servicea2dp service。这之中比较重要的是构造了bluetoothadapater的状态机,这个是后期蓝牙各种状态变化的基础,同时启动了eventloop用于处理从dbus过来的各种event,这两者晓东会另开篇幅和大家详细介绍。

猜你喜欢

转载自blog.csdn.net/lucky_liuxiang/article/details/80232104