• (转)android4.0蓝牙使能的详细解析


    内容简介:本文详细分析了android4.0 中蓝牙使能的过程,相比较android2.3,4.0中的蓝牙最大的差别在于UI上on/off的伪开关。在android4.0中加入了 adapter的状态机。所谓的状态机就类似于状态转换图,在一个状态收到某个特定的命令会变成另外一个状态,不同的命令可以跳转到不同的状态(当然也有 可能到同一状态)。adapter的初始状态为poweroff,在android系统启动的时候会进入warmup状态,同时会进行UUID的add, 该操作会引起propertychanged的UUID signal,该signal会使得状态从warmup变换到hotoff状态。因此在UI端off时其实adapter已经处于hotoff状态而不是 poweroff状态。这一点是很关键的。在正文中,我会从假如我不知道这些开始来描绘整个使能的过程。

    正文:

    毫无疑问,bluetooth的打开是在Settings中进行的操作。因此,冤有头,债有主,我们来到了Settings.java中,果然发现了相关的代码如下:

    mBluetoothEnabler =new BluetoothEnabler(context, new Switch(context));

    于是,我们得以进入真正的蓝牙操作的殿堂,好好进去看看吧。

       1 1、BluetoothEnabler的构造函数
       2   
       3    
       4   
       5       public BluetoothEnabler(Context context,Switch switch_) {
       6   
       7           mContext = context;
       8   
       9           mSwitch = switch_;
      10   
      11   //很简单了,去调用一个LocalBluetoothManager类的getInstance,其实会构造该类的
      12   
      13           LocalBluetoothManager manager =LocalBluetoothManager.getInstance(context);
      14   
      15           if (manager == null) {
      16   
      17               // Bluetooth is not supported
      18   
      19               mLocalAdapter = null;
      20   
      21               mSwitch.setEnabled(false);
      22   
      23           } else {
      24   
      25   //构造成功后,通过manager得到bluetooth的adapter
      26   
      27               mLocalAdapter =manager.getBluetoothAdapter();
      28   
      29           }
      30   
      31   //同时新建一个intent,用于接收ACTION_STATE_CHANGED
      32   
      33           mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
      34   
      35       }
      36   
      37    
      38   
      39 2、LocalBluetoothManager类的getInstance
      40   
      41       public static synchronized LocalBluetoothManager getInstance(Context context) {
      42   
      43           if (sInstance == null) {
      44   
      45   //2.1同样的,这个会去调用LocalBluetoothAdapter的getInstance,也会构造该类
      46   
      47               LocalBluetoothAdapter adapter =LocalBluetoothAdapter.getInstance();
      48   
      49               if (adapter == null) {
      50   
      51                   return null;
      52   
      53               }
      54   
      55               // This will be around as long asthis process is
      56   
      57               Context appContext =context.getApplicationContext();
      58   
      59   //2.2构造LocalBluetoothManager类
      60   
      61               sInstance = new LocalBluetoothManager(adapter, appContext);
      62   
      63           }
      64   
      65    
      66   
      67           return sInstance;
      68   
      69       }
      70   
      71 2.1 LocalBluetoothAdapter的getInstance
      72   
      73    
      74   
      75       static synchronized LocalBluetoothAdapter getInstance() {
      76   
      77           if (sInstance == null) {
      78   
      79   //2.1.1通过BluetoothAdapter得到DefaultAdapter
      80   
      81               BluetoothAdapter adapter =BluetoothAdapter.getDefaultAdapter();
      82   
      83               if (adapter != null) {
      84   
      85   //2.1.2若有该DefaultAdapter,则构造LocalBluetoothAdapter
      86   
      87                   sInstance = new LocalBluetoothAdapter(adapter);
      88   
      89               }
      90   
      91           }
      92   
      93    
      94   
      95           return sInstance;
      96   
      97       }
      98   
      99    
     100   
     101 2.1.1BluetoothAdapter得到DefaultAdapter
     102   
     103    
     104   
     105       public static synchronized BluetoothAdapter getDefaultAdapter() {
     106   
     107           if (sAdapter == null) {
     108   
     109               IBinder b =ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
     110   
     111               if (b != null) {
     112   
     113                   IBluetooth service =IBluetooth.Stub.asInterface(b);
     114   
     115                   sAdapter = new BluetoothAdapter(service);
     116   
     117               }
     118   
     119           }
     120   
     121           return sAdapter;
     122   
     123       }
     124   
     125    
     126   
     127 2.1.2构造LocalBluetoothAdapter
     128   
     129   //其实就是 mAdapter的初始化而已
     130   
     131       private LocalBluetoothAdapter(BluetoothAdapter adapter) {
     132   
     133           mAdapter = adapter;
     134   
     135       }
     136   
     137 2.2构造LocalBluetoothManager类
     138   
     139   //管理本地蓝牙类,用来在蓝牙API子类上面再封装一个接口
     140   
     141       private LocalBluetoothManager(LocalBluetoothAdapter adapter, Context context) {
     142   
     143           mContext = context;
     144   
     145   //mLocalAdapter初始化为DefaultAdapter中得到的值
     146   
     147   mLocalAdapter= adapter;
     148   
     149   //构造CachedBluetoothDeviceManager,用来管理远程蓝牙设备
     150   
     151           mCachedDeviceManager = new CachedBluetoothDeviceManager(context);
     152   
     153   //2.2.1构建BluetoothEventManager,该类是用来管理广播消息和回调函数的,即分发不同的消息去对UI进行处理
     154   
     155           mEventManager = new BluetoothEventManager(mLocalAdapter,
     156   
     157                   mCachedDeviceManager, context);
     158   
     159   //2.2.2该类提供对不同LocalBluetoothProfile object的访问
     160   
     161           mProfileManager = new LocalBluetoothProfileManager(context,
     162   
     163                   mLocalAdapter,mCachedDeviceManager, mEventManager);
     164   
     165       }
     166   
     167    
     168   
     169 2.2.1构建BluetoothEventManager
     170   
     171    
     172   
     173       BluetoothEventManager(LocalBluetoothAdapteradapter,
     174   
     175               CachedBluetoothDeviceManagerdeviceManager, Context context) {
     176   
     177           mLocalAdapter = adapter;
     178   
     179           mDeviceManager = deviceManager;
     180   
     181   //创建两个IntentFilter
     182   
     183           mAdapterIntentFilter = new IntentFilter();
     184   
     185   //这里没有对mProfileIntentFilter进行初始化,这个在LocalBluetoothProfileManager的addProfile中实现
     186   
     187           mProfileIntentFilter = new IntentFilter();
     188   
     189   //创建一个Handler的Hash表
     190   
     191           mHandlerMap = new HashMap<String,Handler>();
     192   
     193           mContext = context;
     194   
     195    
     196   
     197   //注册对adapter和Device的几个广播消息的处理回调函数
     198   
     199   //add action到mAdapterIntentFilter
     200   
     201           // Bluetooth on/off broadcasts
     202   
     203          addHandler(BluetoothAdapter.ACTION_STATE_CHANGED, newAdapterStateChangedHandler());
     204   
     205    
     206   
     207           // Discovery broadcasts
     208   
     209          addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED, newScanningStateChangedHandler(true));
     210   
     211          addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED, newScanningStateChangedHandler(false));
     212   
     213          addHandler(BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler());
     214   
     215          addHandler(BluetoothDevice.ACTION_DISAPPEARED, newDeviceDisappearedHandler());
     216   
     217          addHandler(BluetoothDevice.ACTION_NAME_CHANGED, newNameChangedHandler());
     218   
     219    
     220   
     221           // Pairing broadcasts
     222   
     223          addHandler(BluetoothDevice.ACTION_BOND_STATE_CHANGED, newBondStateChangedHandler());
     224   
     225          addHandler(BluetoothDevice.ACTION_PAIRING_CANCEL, newPairingCancelHandler());
     226   
     227    
     228   
     229           // Fine-grained state broadcasts
     230   
     231          addHandler(BluetoothDevice.ACTION_CLASS_CHANGED, newClassChangedHandler());
     232   
     233          addHandler(BluetoothDevice.ACTION_UUID,new UuidChangedHandler());
     234   
     235    
     236   
     237           // Dock event broadcasts
     238   
     239          addHandler(Intent.ACTION_DOCK_EVENT,new DockEventHandler());
     240   
     241          //mAdapterIntentFilter的接收处理函数
     242   
     243          mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter);
     244   
     245       }
     246   
     247    
     248   
     249 2.2.2构造LocalBluetoothProfileManager类
     250   
     251    
     252   
     253       LocalBluetoothProfileManager(Contextcontext,
     254   
     255               LocalBluetoothAdapter adapter,
     256   
     257               CachedBluetoothDeviceManagerdeviceManager,
     258   
     259               BluetoothEventManager eventManager){
     260   
     261           mContext = context;
     262   
     263    
     264   
     265           //各个类之间进行关联
     266   
     267           mLocalAdapter = adapter;
     268   
     269           mDeviceManager = deviceManager;
     270   
     271           mEventManager = eventManager;
     272   
     273           // pass this reference to adapter andevent manager (circular dependency)
     274   
     275           mLocalAdapter.setProfileManager(this);
     276   
     277           mEventManager.setProfileManager(this);
     278   
     279    
     280   
     281           ParcelUuid[] uuids =adapter.getUuids();
     282   
     283    
     284   
     285           // uuids may be null if Bluetooth isturned off
     286   
     287           if (uuids != null) {
     288   
     289   //假如已经有了uuid,根据uuid来add并new对应的profile,只针对A2DP,HFP,HSP,OPP四个profile,HID和PAN在下面,每次都add
     290   
     291               updateLocalProfiles(uuids);
     292   
     293           }
     294   
     295    
     296   
     297           // Always add HID and PAN profiles
     298   
     299   //加入HID和PAN两个profile
     300   
     301           mHidProfile = new HidProfile(context,mLocalAdapter);
     302   
     303           addProfile(mHidProfile,HidProfile.NAME,
     304   
     305                  BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
     306   
     307    
     308   
     309           mPanProfile = new PanProfile(context);
     310   
     311           addPanProfile(mPanProfile,PanProfile.NAME,
     312   
     313                  BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
     314   
     315    
     316   
     317           Log.d(TAG,"LocalBluetoothProfileManager construction complete");
     318   
     319       }
     320   
     321    
     322   
    好吧,其实我们被骗了,刚刚只是一个路引,不是真正的操作,真正的操作向来都是从你滑动界面那个on/off键开始的,因此我们决定把这个键的处理给揪出来。在Settings界面上一共就只有两个on/off键,一个是wifi,另一个就是蓝牙了,我们从这个代码入手:
     324   
     325                   case HEADER_TYPE_SWITCH:
     326   
     327   //其实写这个代码的人也比较心虚,假如switch多一点,下面就要重写了
     328   
     329                       // Would need a differenttreatment if the main menu had more switches
     330   
     331                       if (header.id ==R.id.wifi_settings) {
     332   
     333                          mWifiEnabler.setSwitch(holder.switch_);
     334   
     335                       } else {
     336   
     337   //这个就是处理了,上面的路引没有白做啊
     338   
     339                          mBluetoothEnabler.setSwitch(holder.switch_);
     340   
     341                       }
     342   
     343    
     344   
     345 3、mBluetoothEnabler.setSwitch分析
     346   
     347    
     348   
     349       public void setSwitch(Switch switch_) {
     350   
     351   //若是和上次相同,则不做任何事情,可以理解,代码也懒嘛
     352   
     353           if (mSwitch == switch_) return;
     354   
     355   //把上次的switch的changelistener清空
     356   
     357          mSwitch.setOnCheckedChangeListener(null);
     358   
     359           mSwitch = switch_;
     360   
     361   //重设这次的switch的changelistener
     362   
     363          mSwitch.setOnCheckedChangeListener(this);
     364   
     365    
     366   
     367           int bluetoothState =BluetoothAdapter.STATE_OFF;
     368   
     369   //获取getBluetoothState,这个过程也会同步一下state,防止改变
     370   
     371           if (mLocalAdapter != null)bluetoothState = mLocalAdapter.getBluetoothState();
     372   
     373   //根据状态设置一下两个标志位
     374   
     375           boolean isOn = bluetoothState == BluetoothAdapter.STATE_ON;
     376   
     377           boolean isOff = bluetoothState == BluetoothAdapter.STATE_OFF;
     378   
     379   //设置checked的状态位。注意,假如这里状态发生了改变,则会调用this.onCheckedChanged来进行处理
     380   
     381           mSwitch.setChecked(isOn);
     382   
     383           if(WirelessSettings.isRadioAllowed(mContext, Settings.System.RADIO_BLUETOOTH)) {
     384   
     385   //有bluetooth或者不是airplane,则该switch不变灰,否则,灰的。
     386   
     387               mSwitch.setEnabled(isOn || isOff);
     388   
     389           } else {
     390   
     391               mSwitch.setEnabled(false);
     392   
     393           }
     394   
     395       }
     396   
     397    
     398   
     399 4、onCheckedChanged
     400   
     401   在switch状态发生改变后,会调用这个地方的回调函数进行处理。
     402   
     403    
     404   
     405       public void onCheckedChanged(CompoundButtonbuttonView, boolean isChecked) {
     406   
     407           // Show toast message if Bluetooth isnot allowed in airplane mode
     408   
     409   //若是打开的话,就需要检查一下是否allow Bluetooth(radio,airplane的check)
     410   
     411           if (isChecked &&
     412   
     413                  !WirelessSettings.isRadioAllowed(mContext,Settings.System.RADIO_BLUETOOTH)) {
     414   
     415               Toast.makeText(mContext,R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
     416   
     417               // Reset switch to off
     418   
     419   //若是不对的话,reset为off
     420   
     421               buttonView.setChecked(false);
     422   
     423           }
     424   
     425    
     426   
     427           if (mLocalAdapter != null) {
     428   
     429   //4.1设置scanmode,放心,它会判断state的,不是STATE_ON,会直接返回false的
     430   
     431              mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
     432   
     433   //4.2使能或不使能Bluetooth了
     434   
     435              mLocalAdapter.setBluetoothEnabled(isChecked);
     436   
     437           }
     438   
     439   //过程中还是会反灰,直到setBluetoothEnabled的结果返回会改变switch的状态
     440   
     441           mSwitch.setEnabled(false);
     442   
     443       }
     444   
     445    
     446   
     447 4.1设置scanmod
     448   
     449    
     450   
     451   会调用adapter中的setScanMode,直接去看就可以了,事实上就是设置了两个property标志,没什么
     452   
     453    
     454   
     455       public boolean setScanMode(int mode) {
     456   
     457   //这里把这个代码写出来就是证明一下,STATE_ON才会真正做下去,否则免谈
     458   
     459           if (getState() != STATE_ON) returnfalse;
     460   
     461   //这里会调用对应server中的setScanMode
     462   
     463           return setScanMode(mode, 120);
     464   
     465       }
     466   
     467    
     468   
     469       public synchronized boolean setScanMode(intmode, int duration) {
     470   
     471   //这里有个permission,好像和2.3中不一样,注意一下     mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
     472   
     473   "NeedWRITE_SECURE_SETTINGS permission");
     474   
     475           boolean pairable;
     476   
     477           boolean discoverable;
     478   
     479    
     480   
     481           switch (mode) {
     482   
     483           case BluetoothAdapter.SCAN_MODE_NONE:
     484   
     485               pairable = false;
     486   
     487               discoverable = false;
     488   
     489               break;
     490   
     491           caseBluetoothAdapter.SCAN_MODE_CONNECTABLE:
     492   
     493   //开始就是这里了,可pairable,但是不可discoverable
     494   
     495               pairable = true;
     496   
     497               discoverable = false;
     498   
     499               break;
     500   
     501           caseBluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
     502   
     503               pairable = true;
     504   
     505               discoverable = true;
     506   
     507               if (DBG) Log.d(TAG, "BTDiscoverable for " + duration + " seconds");
     508   
     509               break;
     510   
     511           default:
     512   
     513               Log.w(TAG, "Requested invalidscan mode " + mode);
     514   
     515               return false;
     516   
     517           }
     518   
     519    
     520   
     521   //设置这两个property标志
     522   
     523          setPropertyBoolean("Discoverable", discoverable);
     524   
     525          setPropertyBoolean("Pairable", pairable);
     526   
     527           return true;
     528   
     529       }
     530   
     531    
     532   
     533 4.2setBluetoothEnabled分析
     534   
     535    
     536   
     537       public void setBluetoothEnabled(booleanenabled) {
     538   
     539   //根据enabled的标志设置是enable还是disable,在2.3中,这个地方就是bt_enable哦,这里还不知道,我们在第5步进行详细的分析
     540   
     541           boolean success = enabled
     542   
     543                   ? mAdapter.enable()
     544   
     545                   : mAdapter.disable();
     546   
     547   //成功了,设置对应的状态位
     548   
     549           if (success) {
     550   
     551               setBluetoothStateInt(enabled
     552   
     553                   ?BluetoothAdapter.STATE_TURNING_ON
     554   
     555                   :BluetoothAdapter.STATE_TURNING_OFF);
     556   
     557           } else {
     558   
     559               if (Utils.V) {
     560   
     561                   Log.v(TAG,"setBluetoothEnabled call, manager didn't return " +
     562   
     563                           "success forenabled: " + enabled);
     564   
     565               }
     566   
     567   //同步一下设置的状态
     568   
     569               syncBluetoothState();
     570   
     571           }
     572   
     573       }
     574   
     575   }
     576   
     577    
     578   
     579 5、mAdapter.enable或者mAdapter.disable
     580   
     581    
     582   
     583   就先分析enable吧,它会调用对应server端的enable(ture),我们来看看源码
     584   
     585    
     586   
     587       public synchronized boolean enable(booleansaveSetting) {
     588   
     589          mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
     590   
     591                                                  "Need BLUETOOTH_ADMIN permission");
     592   
     593    
     594   
     595           // Airplane mode can prevent Bluetoothradio from being turned on.
     596   
     597   //检查是否是飞行模式
     598   
     599           if (mIsAirplaneSensitive &&isAirplaneModeOn() && !mIsAirplaneToggleable) {
     600   
     601               return false;
     602   
     603           }
     604   
     605   //5.1注意与2.3的不同,在2.3中,这里会调用enablethread去调用native的bt_enable,而4.0没有这么做。没事,我们来分析4.0怎么做的。
     606   
     607          mBluetoothState.sendMessage(BluetoothAdapterStateMachine.USER_TURN_ON,saveSetting);
     608   
     609           return true;
     610   
     611       }
     612   
     613    
     614   
     615 5.1mBluetoothState.sendMessage
     616   
     617    
     618   
    简单理解一下,mBluetoothState是BluetoothAdapterStateMachine类。因此,在分析的之前,简单说一下,它其实就是类似一个状态转换图,根据你所处于的状态,然后再判断收到的操作,进行不同的处理。根据构造函数中的setInitialState(mPowerOff);可以知道初始状态是PowerOff。但是从它给出的状态机可以看出,在PowerOff的状态时,它是通过TURN_HOT/TURN_ON来改变到HotOff状态的,然后才会收到USER_TURN_ON,去该变到BluetootOn的状态。因此,可以肯定的是我们这里的USER_TURN_ON不是它收到的第一个message,因此我们去纠结一下它是从哪里开始改变PowerOff的状态:extra1,然后再来看这里的处理吧:5.2 620   
     621    
     622   
     623   extra1、mAdapter.enable之前的状态机转变
     624   
     625    
     626   
     627   众所周知,android在启动之后会启动一个serverThread的线程,通过这个线程会启动一系列的服务。我们的蓝牙服务也是在这里启动的,android4.0其实在这个地方对状态机进行了修改,我们来看一下源码:
     628   
     629   该代码位于framworks/base/services/java/com/android/server/systemserver.java
     630   
     631   BluetoothServicebluetooth = null;
     632   
     633   BluetoothA2dpServicebluetoothA2dp = null;
     634   
     635    
     636   
     637   //模拟器上是不支持Bluetooth的,工厂测试模式也没有Bluetooth(这个不了解)
     638   
     639               // Skip Bluetooth if we have anemulator kernel
     640   
     641               // TODO: Use a more reliable checkto see if this product should
     642   
     643               // support Bluetooth - see bug988521
     644   
     645               if(SystemProperties.get("ro.kernel.qemu").equals("1")) {
     646   
     647                   Slog.i(TAG, "No BluetoohService (emulator)");
     648   
     649               } else if (factoryTest ==SystemServer.FACTORY_TEST_LOW_LEVEL) {
     650   
     651                   Slog.i(TAG, "No BluetoothService (factory test)");
     652   
     653               } else {
     654   
     655                   Slog.i(TAG, "BluetoothService");
     656   
     657   //新建Bluetoothservice,并把他加入到ServiceManager中
     658   
     659                   bluetooth = newBluetoothService(context);
     660   
     661                  ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE,bluetooth);
     662   
     663   //extra1.1在启动Bluetooth服务后进行一些初始化,呵呵,这里就对状态机进行了改变
     664   
     665                  bluetooth.initAfterRegistration();
     666   
     667    
     668   
     669   //新建了BluetoothA2dpService,并把之加入到了ServiceManager中
     670   
     671   bluetoothA2dp= new BluetoothA2dpService(context, bluetooth);
     672   
     673                  ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
     674   
     675                                            bluetoothA2dp);
     676   
     677   //extra1.2同样的要在之后做些init的工作
     678   
     679                  bluetooth.initAfterA2dpRegistration();
     680   
     681   //得到是否飞行
     682   
     683                   int airplaneModeOn =Settings.System.getInt(mContentResolver,
     684   
     685                          Settings.System.AIRPLANE_MODE_ON, 0);
     686   
     687   //看Bluetooth是否on,若是打开的状态(没有飞行),则这里会调用enable去打开
     688   
     689                   int bluetoothOn =Settings.Secure.getInt(mContentResolver,
     690   
     691                      Settings.Secure.BLUETOOTH_ON, 0);
     692   
     693                   if (airplaneModeOn == 0&& bluetoothOn != 0) {
     694   
     695                       bluetooth.enable();
     696   
     697                   }
     698   
     699               }
     700   
     701    
     702   
     703   extra1.1 initAfterRegistration分析
     704   
     705    
     706   
     707       public synchronized voidinitAfterRegistration() {
     708   
     709   //得到default的adapter
     710   
     711           mAdapter =BluetoothAdapter.getDefaultAdapter();
     712   
     713   //创建BluetoothAdapterStateMachine,初始化几个状态,并设初始状态位POWEROFF,这里同时新建了一个EventLoop
     714   
     715           mBluetoothState = newBluetoothAdapterStateMachine(mContext, this, mAdapter);
     716   
     717           mBluetoothState.start();
     718   
     719   //根据这个xml的bool变量来决定是否先期TURN_HOT,该变量位于frameworks/base/core/res/res/values/config.xml中,默认为true
     720   
     721           if (mContext.getResources().getBoolean
     722   
     723              (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
     724   
     725   //extra1.2发送TURN_HOT的状态变化message
     726   
     727              mBluetoothState.sendMessage(BluetoothAdapterStateMachine.TURN_HOT);
     728   
     729           }
     730   
     731   //得到对应的EventLoop
     732   
     733           mEventLoop =mBluetoothState.getBluetoothEventLoop();
     734   
     735       }
     736   
     737    
     738   
     739   extra1.2  TURN_HOT message的处理
     740   
     741    
     742   
     743       /**
     744   
     745        * Bluetooth module's power is off,firmware is not loaded.
     746   
     747        */
     748   
     749       private class PowerOff extends State {
     750   
     751           @Override
     752   
     753           public void enter() {
     754   
     755               if (DBG) log("Enter PowerOff:" + getCurrentMessage().what);
     756   
     757           }
     758   
     759           @Override
     760   
     761           public boolean processMessage(Messagemessage) {
     762   
     763               log("PowerOff process message:" + message.what);
     764   
     765    
     766   
     767               boolean retValue = HANDLED;
     768   
     769               switch(message.what) {
     770   
     771   ……
     772   
     773                  case TURN_HOT:
     774   
     775   //extra1.3这里就是我们寻找了千年的bt_enable所在的地方。我们去看看
     776   
     777                       if (prepareBluetooth()) {
     778   
     779   //extra1.5转变状态到warmup,在prepareBluetooth真正完成后,这个状态还会发生改变
     780   
     781                           transitionTo(mWarmUp);
     782   
     783                       }
     784   
     785                       break;
     786   
     787   ……
     788   
     789    
     790   
     791   extra1.3prepareBluetooth分析
     792   
     793    
     794   
     795   看英文注释就知道了,不解释
     796   
     797           /**
     798   
     799            * Turn on Bluetooth Module, Loadfirmware, and do all the preparation
     800   
     801            * needed to get the Bluetooth Moduleready but keep it not discoverable
     802   
     803            * and not connectable.
     804   
     805            * The last step of this method sets upthe local service record DB.
     806   
     807            * There will be a event reporting thestatus of the SDP setup.
     808   
     809            */
     810   
     811           private boolean prepareBluetooth() {
     812   
     813   //extra1.4首先还是调用了enableNative的本地方法,到这里你会发现终于和2.3相似了(不过请注意调用的时机不同了,这个在初始化,而2.3在界面的on/off滑动的时候),它还是会调用bt_enable,这个就会调用对应的set_bluetooth_power了
     814   
     815               if(mBluetoothService.enableNative() != 0) {
     816   
     817                   return false;
     818   
     819               }
     820   
     821    
     822   
     823               // try to start event loop, give 2attempts
     824   
     825   //尝试两次去start event loop
     826   
     827               int retryCount = 2;
     828   
     829               boolean eventLoopStarted = false;
     830   
     831               while ((retryCount-- > 0)&& !eventLoopStarted) {
     832   
     833                   mEventLoop.start();
     834   
     835                   // it may take a moment for theother thread to do its
     836   
     837                   // thing.  Check periodically for a while.
     838   
     839                   int pollCount = 5;
     840   
     841                   while ((pollCount-- > 0)&& !eventLoopStarted) {
     842   
     843                       if(mEventLoop.isEventLoopRunning()) {
     844   
     845                           eventLoopStarted =true;
     846   
     847                           break;
     848   
     849                       }
     850   
     851                       try {
     852   
     853                           Thread.sleep(100);
     854   
     855                       } catch(InterruptedException e) {
     856   
     857                          log("prepareBluetooth sleep interrupted: " + pollCount);
     858   
     859                           break;
     860   
     861                       }
     862   
     863                   }
     864   
     865               }
     866   
     867   //出错处理
     868   
     869               if (!eventLoopStarted) {
     870   
     871                  mBluetoothService.disableNative();
     872   
     873                   return false;
     874   
     875               }
     876   
     877    
     878   
     879               // get BluetoothService ready
     880   
     881   //建立native data以及SDP相关的一些操作,这里将会产生PropertyChanged的UUIDs的signal,对该信号的处理会对状态发生改变,详细分析见extra1.5
     882   
     883               if(!mBluetoothService.prepareBluetooth()) {
     884   
     885                   mEventLoop.stop();
     886   
     887                  mBluetoothService.disableNative();
     888   
     889                   return false;
     890   
     891               }
     892   
     893   //设置一个prepare的超时处理,在该时间内没有收到UUID changed的signal将会进行错误处理
     894   
     895              sendMessageDelayed(PREPARE_BLUETOOTH_TIMEOUT,PREPARE_BLUETOOTH_TIMEOUT_TIME);
     896   
     897               return true;
     898   
     899           }
     900   
     901       }
     902   
     903    
     904   
     905   extra1.4  bt_enable分析
     906   
     907    
     908   
     909   intbt_enable() {
     910   
     911       LOGV(__FUNCTION__);
     912   
     913    
     914   
     915       int ret = -1;
     916   
     917       int hci_sock = -1;
     918   
     919       int attempt;
     920   
     921    
     922   
     923   //power的设置,on。不解释,可加入对应板子的gpio口的处理,默认就只用了rfkill的处理
     924   
     925       if (set_bluetooth_power(1) < 0) gotoout;
     926   
     927   //开始hciattach服务,这个我们也做了修改,加入了rtk_h5
     928   
     929       LOGI("Starting hciattachdaemon");
     930   
     931       if (property_set("ctl.start","hciattach") < 0) {
     932   
     933           LOGE("Failed to starthciattach");
     934   
     935           set_bluetooth_power(0);
     936   
     937           goto out;
     938   
     939       }
     940   
     941    
     942   
     943    
     944   
     945       // Try for 10 seconds, this can onlysucceed once hciattach has sent the
     946   
     947       // firmware and then turned on hci devicevia HCIUARTSETPROTO ioctl
     948   
     949       for (attempt = 1000; attempt > 0;  attempt--) {
     950   
     951   //创建hci_sock
     952   
     953           hci_sock = create_hci_sock();
     954   
     955           if (hci_sock < 0) goto out;
     956   
     957   //调用ioctl的HCIDEVUP,来判断hciattach是否已经ok了。
     958   
     959           ret = ioctl(hci_sock, HCIDEVUP,HCI_DEV_ID);
     960   
     961    
     962   
     963           LOGI("bt_enable: ret: %d, errno:%d", ret, errno);
     964   
     965           if (!ret) {
     966   
     967               break;
     968   
     969           } else if (errno == EALREADY) {
     970   
     971               LOGW("Bluetoothd alreadystarted, unexpectedly!");
     972   
     973               break;
     974   
     975           }
     976   
     977    
     978   
     979           close(hci_sock);
     980   
     981   //等待10 ms后再试一次
     982   
     983           usleep(100000);  // 100 ms retry delay
     984   
     985       }
     986   
     987   //10s都没有搞定,需要做个失败的处理
     988   
     989       if (attempt == 0) {
     990   
     991           LOGE("%s: Timeout waiting for HCIdevice to come up, error- %d, ",
     992   
     993               __FUNCTION__, ret);
     994   
     995           if (property_set("ctl.stop","hciattach") < 0) {
     996   
     997               LOGE("Error stoppinghciattach");
     998   
     999           }
    1000   
    1001           set_bluetooth_power(0);
    1002   
    1003           goto out;
    1004   
    1005       }
    1006   
    1007   //启动bluetoothd服务
    1008   
    1009       LOGI("Starting bluetoothddeamon");
    1010   
    1011       if (property_set("ctl.start","bluetoothd") < 0) {
    1012   
    1013           LOGE("Failed to startbluetoothd");
    1014   
    1015           set_bluetooth_power(0);
    1016   
    1017           goto out;
    1018   
    1019       }
    1020   
    1021    
    1022   
    1023       ret = 0;
    1024   
    1025    
    1026   
    1027   out:
    1028   
    1029   //关闭hci_sock
    1030   
    1031       if (hci_sock >= 0) close(hci_sock);
    1032   
    1033       return ret;
    1034   
    1035   }
    1036   
    1037    
    1038   
    1039   extra 1.5  PropetyChanged的UUIDs的处理
    1040   
    1041    
    1042   
    1043   event_filter是用来对bluez的dbus的signal进行监听的,有signal产生后,会在这里进行处理。因此,我们直接到这里看看该怎么处理。
    1044   
    1045    
    1046   
    1047   //Called by dbus during WaitForAndDispatchEventNative()
    1048   
    1049   staticDBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
    1050   
    1051                                         void*data) {
    1052   
    1053       native_data_t *nat;
    1054   
    1055       JNIEnv *env;
    1056   
    1057       DBusError err;
    1058   
    1059       DBusHandlerResult ret;
    1060   
    1061    
    1062   
    1063   //err的一个初始化
    1064   
    1065       dbus_error_init(&err);
    1066   
    1067   //得到参数
    1068   
    1069       nat = (native_data_t *)data;
    1070   
    1071       nat->vm->GetEnv((void**)&env,nat->envVer);
    1072   
    1073       if (dbus_message_get_type(msg) !=DBUS_MESSAGE_TYPE_SIGNAL) {
    1074   
    1075           LOGV("%s: not interested (not asignal).", __FUNCTION__);
    1076   
    1077           returnDBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    1078   
    1079       }
    1080   
    1081    
    1082   
    1083       LOGV("%s: Received signal %s:%s from%s", __FUNCTION__,
    1084   
    1085           dbus_message_get_interface(msg),dbus_message_get_member(msg),
    1086   
    1087           dbus_message_get_path(msg));
    1088   
    1089    
    1090   
    1091       env->PushLocalFrame(EVENT_LOOP_REFS);
    1092   
    1093   ……
    1094   
    1095   //PropertyChanged这个signal的处理
    1096   
    1097       } else if (dbus_message_is_signal(msg,
    1098   
    1099                                        "org.bluez.Adapter",
    1100   
    1101                                        "PropertyChanged")) {
    1102   
    1103   //由msg解析参数
    1104   
    1105           jobjectArray str_array =parse_adapter_property_change(env, msg);
    1106   
    1107           if (str_array != NULL) {
    1108   
    1109               /* Check if bluetoothd has(re)started, if so update the path. */
    1110   
    1111               jstring property =(jstring)env->GetObjectArrayElement(str_array, 0);
    1112   
    1113               const char *c_property =env->GetStringUTFChars(property, NULL);
    1114   
    1115   //检查Property是否started
    1116   
    1117               if (!strncmp(c_property,"Powered", strlen("Powered"))) {
    1118   
    1119   //若是powered,则看value是否是true,是ture就得到对应的path
    1120   
    1121                   jstring value =
    1122   
    1123                       (jstring)env->GetObjectArrayElement(str_array, 1);
    1124   
    1125                   const char *c_value =env->GetStringUTFChars(value, NULL);
    1126   
    1127                   if (!strncmp(c_value,"true", strlen("true")))
    1128   
    1129                       nat->adapter =get_adapter_path(nat->conn);
    1130   
    1131                  env->ReleaseStringUTFChars(value, c_value);
    1132   
    1133               }
    1134   
    1135              env->ReleaseStringUTFChars(property, c_property);
    1136   
    1137   //extra1.6调用对应的method_onPropertyChanged函数,该method对应的onPropertyChanged函数
    1138   
    1139               env->CallVoidMethod(nat->me,
    1140   
    1141                                method_onPropertyChanged,
    1142   
    1143                                 str_array);
    1144   
    1145           } elseLOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
    1146   
    1147           goto success;
    1148   
    1149   ……
    1150   
    1151    
    1152   
    1153   extra1.6  真正的处理函数onPropertyChanged分析
    1154   
    1155    
    1156   
    1157    /**
    1158   
    1159        * Called by native code on aPropertyChanged signal from
    1160   
    1161        * org.bluez.Adapter. This method is alsocalled from
    1162   
    1163        * {@link BluetoothAdapterStateMachine} toset the "Pairable"
    1164   
    1165        * property when Bluetooth is enabled.
    1166   
    1167        *
    1168   
    1169        * @param propValues a string arraycontaining the key and one or more
    1170   
    1171        * values.
    1172   
    1173        */
    1174   
    1175       /*package*/ void onPropertyChanged(String[]propValues) {
    1176   
    1177           BluetoothAdapterPropertiesadapterProperties =
    1178   
    1179                  mBluetoothService.getAdapterProperties();
    1180   
    1181   //先fill up cache
    1182   
    1183           if (adapterProperties.isEmpty()) {
    1184   
    1185               // We have got a property changebefore
    1186   
    1187               // we filled up our cache.
    1188   
    1189              adapterProperties.getAllProperties();
    1190   
    1191           }
    1192   
    1193           log("Property Changed: " +propValues[0] + " : " + propValues[1]);
    1194   
    1195           String name = propValues[0];
    1196   
    1197   ……
    1198   
    1199   //对UUIDs的处理
    1200   
    1201           } else if(name.equals("Devices") || name.equals("UUIDs")) {
    1202   
    1203               String value = null;
    1204   
    1205               int len =Integer.valueOf(propValues[1]);
    1206   
    1207               if (len > 0) {
    1208   
    1209                   StringBuilder str = newStringBuilder();
    1210   
    1211                   for (int i = 2; i <propValues.length; i++) {
    1212   
    1213                       str.append(propValues[i]);
    1214   
    1215                       str.append(",");
    1216   
    1217                   }
    1218   
    1219                   value = str.toString();
    1220   
    1221               }
    1222   
    1223   //把name和value值加入到property的map中
    1224   
    1225               adapterProperties.setProperty(name,value);
    1226   
    1227   //extra1.7有UUIDs的change signal会刷新Bluetooth的State
    1228   
    1229               if (name.equals("UUIDs")){
    1230   
    1231                  mBluetoothService.updateBluetoothState(value);
    1232   
    1233               }
    1234   
    1235   //对Pairable和Discoverable的处理
    1236   
    1237          } else if(name.equals("Pairable") || name.equals("Discoverable")) {
    1238   
    1239               adapterProperties.setProperty(name,propValues[1]);
    1240   
    1241    
    1242   
    1243               if(name.equals("Discoverable")) {
    1244   
    1245      //5.6发送SCAN_MODE_CHANGED的msg,去改变状态机      mBluetoothState.sendMessage(BluetoothAdapterStateMachine.SCAN_MODE_CHANGED);
    1246   
    1247               }
    1248   
    1249   //设置对应的property
    1250   
    1251               String pairable =name.equals("Pairable") ? propValues[1] :
    1252   
    1253                  adapterProperties.getProperty("Pairable");
    1254   
    1255               String discoverable =name.equals("Discoverable") ? propValues[1] :
    1256   
    1257                  adapterProperties.getProperty("Discoverable");
    1258   
    1259    
    1260   
    1261               // This shouldn't happen, unlessAdapter Properties are null.
    1262   
    1263               if (pairable == null ||discoverable == null)
    1264   
    1265                   return;
    1266   
    1267    
    1268   
    1269               int mode =BluetoothService.bluezStringToScanMode(
    1270   
    1271                      pairable.equals("true"),
    1272   
    1273                      discoverable.equals("true"));
    1274   
    1275               if (mode >= 0) {
    1276   
    1277   //当pairable和discoverable均为true的时候,会发送一个ACTION_SCAN_MODE_CHANGED的广播消息
    1278   
    1279                   Intent intent = newIntent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
    1280   
    1281                  intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, mode);
    1282   
    1283                  intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
    1284   
    1285                   mContext.sendBroadcast(intent,BLUETOOTH_PERM);
    1286   
    1287               }
    1288   
    1289           }
    1290   
    1291    
    1292   
    1293   ……
    1294   
    1295    
    1296   
    1297   extra1.7  UUIDs改变带来的State的刷新
    1298   
    1299   
    1300       /**
    1301   
    1302        * This function is called from BluetoothEvent Loop when onPropertyChanged
    1303   
    1304        * for adapter comes in with UUID property.
    1305   
    1306        * @param uuidsThe uuids of adapter asreported by Bluez.
    1307   
    1308        */
    1309   
    1310       /*package*/ synchronized voidupdateBluetoothState(String uuids) {
    1311   
    1312           ParcelUuid[] adapterUuids =convertStringToParcelUuid(uuids);
    1313   
    1314   //为什么必须包含所有已经有的uuid??感觉有点反了,再看看
    1315   
    1316           if (mAdapterUuids != null &&
    1317   
    1318              BluetoothUuid.containsAllUuids(adapterUuids, mAdapterUuids)) {
    1319   
    1320   //放SERVICE_RECORD_LOADED的信息,此时,处于warm up状态,看extra1.8分析状态如何继续改变          mBluetoothState.sendMessage(BluetoothAdapterStateMachine.SERVICE_RECORD_LOADED);
    1321   
    1322           }
    1323   
    1324       }
    1325   
    1326    
    1327   
    1328   extra1.8 UUIDs对状态机改变
    1329   
    1330   
    1331      /**
    1332   
    1333        * Turning on Bluetooth module's power,loading firmware, starting
    1334   
    1335        * event loop thread to listen on Bluetoothmodule event changes.
    1336   
    1337        */
    1338   
    1339       private class WarmUp extends State {
    1340   
    1341  
    1342           @Override
    1343   
    1344           public void enter() {
    1345   
    1346               if (DBG) log("Enter WarmUp:" + getCurrentMessage().what);
    1347   
    1348           }
    1349   
    1350   
    1351           @Override
    1352   
    1353           public boolean processMessage(Messagemessage) {
    1354   
    1355               log("WarmUp process message:" + message.what);
    1356   
    1357               boolean retValue = HANDLED;
    1358   
    1359               switch(message.what) {
    1360   
    1361                   case SERVICE_RECORD_LOADED:
    1362   
    1363   //可以看到,首先会把当时从poweroff过来的一个超时message拿remove了。
    1364   
    1365                      removeMessages(PREPARE_BLUETOOTH_TIMEOUT);
    1366   
    1367   //转到hotoff状态,在hotoff状态仍会接收到多个SERVICE_RECORD_LOADED的msg,但是那个状态下该msg将没有任何handled,因此会一直处于hotoff状态
    1368   
    1369                       transitionTo(mHotOff);
    1370   
    1371                       break;
    1372   
    1373   ……
    1374   
    1375    
    1376   
    1377   5.2 mAdapter.enable中mBluetoothState.sendMessage后的状态机处理
    1378   
    1379    
    1380   
    1381   由extra的分析可知,此时,Bluetooth的State已经处于HotOff状态了,所以,从这里开始处理State的变换。
    1382   
    1383    
    1384   
    1385       /**
    1386   
    1387        * Bluetooth Module has powered, firmwareloaded, event loop started,
    1388   
    1389        * SDP loaded, but the modules staysnon-discoverable and
    1390   
    1391        * non-connectable.
    1392   
    1393        */
    1394   
    1395       private class HotOff extends State {
    1396   
    1397           @Override
    1398   
    1399           public void enter() {
    1400   
    1401               if (DBG) log("Enter HotOff:" + getCurrentMessage().what);
    1402   
    1403           }
    1404   
    1405    
    1406   
    1407           @Override
    1408   
    1409           public boolean processMessage(Messagemessage) {
    1410   
    1411               log("HotOff process message:" + message.what);
    1412   
    1413    
    1414   
    1415               boolean retValue = HANDLED;
    1416   
    1417               switch(message.what) {
    1418   
    1419                   case USER_TURN_ON:
    1420   
    1421   //发出BluetoothAdapter.STATE_TURNING_ON的广播消息
    1422   
    1423                      broadcastState(BluetoothAdapter.STATE_TURNING_ON);
    1424   
    1425                       if ((Boolean) message.obj){
    1426   
    1427   //就是把Settings.Secure.BLUETOOTH_ON设为1。用于标志Bluetooth enable了
    1428   
    1429                          persistSwitchSetting(true);
    1430   
    1431                       }
    1432   
    1433                       // let it fall toTURN_ON_CONTINUE:
    1434   
    1435                       //$FALL-THROUGH$
    1436   
    1437   //注意上面没有break哦
    1438   
    1439                   case TURN_ON_CONTINUE:
    1440   
    1441   //这里就是把Bluetooth设为connectable就是Powered=1,这里就把prepareBluetooth中设置的不可连接重新设置回来了。这个重连会产生一些新的变化,它会发送WRITE_SCAN_ENABLE的cmd,因此在该cmd_complete时会有一些新的处理:5.3,它会再次引起状态机的改变:5.6
    1442   
    1443                      mBluetoothService.switchConnectable(true);
    1444   
    1445   //进入到Switching状态
    1446   
    1447                       transitionTo(mSwitching);
    1448   
    1449                       break;
    1450   
    1451   ……
    1452   
    1453    
    1454   
    1455   5.3 WRITE_SCAN_ENABLE在cmd_complete后的处理
    1456   
    1457    
    1458   
    1459   在bluez中是用cmd_complete函数来监视发出cmd完成后的处理的。该函数具体如下:
    1460   
    1461    
    1462   
    1463   static inline void cmd_complete(int index, void *ptr)
    1464   
    1465   {
    1466   
    1467   struct dev_info *dev = &devs[index];
    1468   
    1469   evt_cmd_complete*evt = ptr;
    1470   
    1471   uint16_topcode = btohs(evt->opcode);
    1472   
    1473   uint8_tstatus = *((uint8_t *) ptr + EVT_CMD_COMPLETE_SIZE);
    1474   
    1475    
    1476   
    1477   switch(opcode) {
    1478   
    1479   ……
    1480   
    1481   //WRITE_SCAN_ENABLE命令完成的处理函数,会再发一个READ_SCAN_ENABLE的命令
    1482   
    1483   case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE):
    1484   
    1485   hci_send_cmd(dev->sk,OGF_HOST_CTL, OCF_READ_SCAN_ENABLE,
    1486   
    1487   0,NULL);
    1488   
    1489   break;
    1490   
    1491   //5.4紧接着就是对READ_SCAN_ENABLE命令完成的处理,它是通过read_scan_complete来实现的
    1492   
    1493   case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SCAN_ENABLE):
    1494   
    1495   ptr+= sizeof(evt_cmd_complete);
    1496   
    1497   read_scan_complete(index,status, ptr);
    1498   
    1499   break;
    1500   
    1501   ……
    1502   
    1503   }
    1504   
    1505    
    1506   
    1507   5.4 read_scan命令完成的处理
    1508   
    1509    
    1510   
    1511   static void read_scan_complete(int index, uint8_t status, void *ptr)
    1512   
    1513   {
    1514   
    1515   struct btd_adapter *adapter;
    1516   
    1517   read_scan_enable_rp*rp = ptr;
    1518   
    1519    
    1520   
    1521   DBG("hci%dstatus %u", index, status);
    1522   
    1523   //由index得到对应的adapter
    1524   
    1525   adapter= manager_find_adapter_by_id(index);
    1526   
    1527   if(!adapter) {
    1528   
    1529   error("Unableto find matching adapter");
    1530   
    1531   return;
    1532   
    1533   }
    1534   
    1535   //5.5这里算是一个通知adapter,mode改变了。
    1536   
    1537   adapter_mode_changed(adapter,rp->enable);
    1538   
    1539   }
    1540   
    1541    
    1542   
    1543   5.5 通知adapter,mode发生了改变
    1544   
    1545   
    1546   void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode)
    1547   
    1548   {
    1549   
    1550   const gchar *path = adapter_get_path(adapter);
    1551   
    1552   gbooleandiscoverable, pairable;
    1553   
    1554   
    1555   DBG("old0x%02x new 0x%02x", adapter->scan_mode, scan_mode);
    1556   
    1557   //若相同,则nothing todo
    1558   
    1559   if(adapter->scan_mode == scan_mode){
    1560   
    1561   #ifdefBOARD_HAVE_BLUETOOTH_BCM
    1562   
    1563       /*we may reset scan_mode already inbtd_adapter_stop(), so comes to here*/
    1564   
    1565       set_mode_complete(adapter);
    1566   
    1567   #endif
    1568   
    1569       return;
    1570   
    1571   }
    1572   
    1573   //把discoverable的timeout清空
    1574   
    1575   adapter_remove_discov_timeout(adapter);
    1576   
    1577   //这里开始,是设为SCAN_PAGE| SCAN_INQUIRY
    1578   
    1579   switch(scan_mode) {
    1580   
    1581   caseSCAN_DISABLED:
    1582   
    1583   adapter->mode= MODE_OFF;
    1584   
    1585   discoverable= FALSE;
    1586   
    1587   pairable= FALSE;
    1588   
    1589   break;
    1590   
    1591   caseSCAN_PAGE:
    1592   
    1593   adapter->mode= MODE_CONNECTABLE;
    1594   
    1595   discoverable= FALSE;
    1596   
    1597   pairable= adapter->pairable;
    1598   
    1599   break;
    1600   
    1601   case(SCAN_PAGE | SCAN_INQUIRY):
    1602   
    1603   //设一下模式,在有reply要求的情况下,该步骤还是很重要的
    1604   
    1605   adapter->mode= MODE_DISCOVERABLE;
    1606   
    1607   discoverable= TRUE;
    1608   
    1609   pairable= adapter->pairable;
    1610   
    1611   //还要设一个discoverable的时间
    1612   
    1613   if(adapter->discov_timeout != 0)
    1614   
    1615   adapter_set_discov_timeout(adapter,
    1616   
    1617   adapter->discov_timeout);
    1618   
    1619   break;
    1620   
    1621   caseSCAN_INQUIRY:
    1622   
    1623   /*Address the scenario where a low-level application like
    1624   
    1625    * hciconfig changed the scan mode */
    1626   
    1627   if(adapter->discov_timeout != 0)
    1628   
    1629   adapter_set_discov_timeout(adapter,
    1630   
    1631   adapter->discov_timeout);
    1632   
    1633    
    1634   
    1635   /*ignore, this event should not be sent */
    1636   
    1637   default:
    1638   
    1639   /*ignore, reserved */
    1640   
    1641   return;
    1642   
    1643   }
    1644   
    1645    
    1646   
    1647   /*If page scanning gets toggled emit the Pairable property */
    1648   
    1649   //这里会发一个property_changed的pairable的signal
    1650   
    1651   if((adapter->scan_mode & SCAN_PAGE) != (scan_mode & SCAN_PAGE))
    1652   
    1653   emit_property_changed(connection,adapter->path,
    1654   
    1655   ADAPTER_INTERFACE,"Pairable",
    1656   
    1657   DBUS_TYPE_BOOLEAN,&pairable);
    1658   
    1659    
    1660   
    1661   if(!discoverable)
    1662   
    1663   adapter_set_limited_discoverable(adapter,FALSE);
    1664   
    1665   //这里会发一个property_changed的discoverable的signal
    1666   
    1667   emit_property_changed(connection,path,
    1668   
    1669   ADAPTER_INTERFACE,"Discoverable",
    1670   
    1671   DBUS_TYPE_BOOLEAN,&discoverable);
    1672   
    1673   adapter->scan_mode= scan_mode;
    1674   
    1675    
    1676   
    1677   set_mode_complete(adapter);
    1678   
    1679   }

    至此,蓝牙的使能主要过程已经全部搞定。


    原文地址:http://blog.csdn.net/xdyang1987/article/details/7771388

  • 相关阅读:
    设计模式-设计原则(Design Principle)
    设计模式-装饰者模式(Decorator Pattern)
    C++-copy constructor、copy-assignment operator、destructor
    cocos2dx3.0-tinyxml在Android环境下解析xml失败的问题
    XACML-条件评估(Condition evaluation),规则评估(Rule evaluation),策略评估(Policy evaluation),策略集评估(PolicySet evaluation)
    XACML-<Target> 元素的结构与相关的评估
    XACML-PolicySet与request结构简介
    从接口自动化测试框架设计到开发(八)--python操作数据库
    从接口自动化测试框架设计到开发(七)--cookie处理
    从接口自动化测试框架设计到开发(六)--持续集成jenkins
  • 原文地址:https://www.cnblogs.com/chenbin7/p/2671907.html
Copyright © 2020-2023  润新知