android - Bluetooth bluetooth (five) answer the phone and listen to music

  1. Bluetooth headset to answer the call

        This would correspond to one of the original intention of HFP (Hands-freeProfile), Free your Hand, Bluetooth. First look at this scene function, the phone calls, phone with a Bluetooth headset is connected, then the process will give priority to trigger code Bluetooth answering the phone, start the code in phone \ src \ com \ android \ phone \ nCallScreen.java of connectBluetoothAudio () / disconnectBluetoothAudio (), a good look at the connecting portion, note the following comments code,
[java]  view plain copy
  1. /* package */ void connectBluetoothAudio() {  
  2.   if (VDBG) log("connectBluetoothAudio()...");  
  3.   if (mBluetoothHeadset != null) {  
  4.       // TODO(BT) check return  
  5.       mBluetoothHeadset.connectAudio();  
  6.   }  
  7.   // Watch out: The bluetooth connection doesn't happen instantly;  
  8.   // the connectAudio() call returns instantly but does its real  
  9.   // work in another thread.  The mBluetoothConnectionPending flag  
  10.   // is just a little trickery to ensure that the onscreen UI updates  
  11.   // instantly. (See isBluetoothAudioConnectedOrPending() above.)  
  12.   mBluetoothConnectionPending = true;  
  13.   mBluetoothConnectionRequestTime = SystemClock.elapsedRealtime();  
         Then you jump to the jurisdiction of Bluetooth applications, code packages / apps / Bluetooth / src / com / android / bluetooth / hfp / HeadsetService.java,
[java]  view plain copy
  1. public boolean connectAudio() {  
  2.     HeadsetService service = getService();  
  3.     if (service == null) return false;  
  4.     return service.connectAudio();  
  5. }  
        Obviously next goal is HeadsetService, look directly at the specific implementation, this part of the code jumps are relatively clear, the following code will first determine the current status is correct, several states can participate on HeadsetStateMachine hold the / packages / apps / Bluetooth / src / com / android / bluetooth / hfp / code comments before most of HeadsetStateMachine.java.
[java]  view plain copy
  1. boolean connectAudio() {  
  2.      // TODO(BT) BLUETOOTH or BLUETOOTH_ADMIN permission  
  3.      enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");  
  4.      if (!mStateMachine.isConnected()) {  
  5.          return false;  
  6.      }  
  7.      if (mStateMachine.isAudioOn()) {  
  8.          return false;  
  9.      }  
  10.      mStateMachine.sendMessage(HeadsetStateMachine.CONNECT_AUDIO);  
  11.      return true;  
  12.  }  
       HeadsetStateMachine into the state machine, find CONNECT_AUDIO branch, see the method connectAudioNative (getByteAddress (mCurrentDevice)) with the Native;
[java]  view plain copy
  1. static jboolean connectAudioNative(JNIEnv *env, jobject object, jbyteArray address) {  
  2.     jbyte *addr;  
  3.     bt_status_t status;  
  4.   
  5.     if (!sBluetoothHfpInterface) return JNI_FALSE;  
  6.   
  7.     addr = env->GetByteArrayElements(address, NULL);  
  8.     if (!addr) {  
  9.         jniThrowIOException (env, chosen);  
  10.         return JNI_FALSE;  
  11.     }  
  12. // connection here  
  13.     if ( (status = sBluetoothHfpInterface->connect_audio((bt_bdaddr_t *)addr)) !=    
  14.          BT_STATUS_SUCCESS) {  
  15.         ALOGE("Failed HF audio connection, status: %d", status);  
  16.     }  
  17.     env->ReleaseByteArrayElements(address, addr, 0);  
  18.     return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;  
  19. }  
       The above code can be further with the following /external/bluetooth/bluedroid/btif/src/btif_hf.c, to actually process is over here, for here the message flow is estimated to be placed after the write
[java]  view plain copy
  1. static bt_status_t connect_audio( bt_bdaddr_t *bd_addr )  
  2. {  
  3.     CHECK_BTHF_INIT();  
  4.     if (is_connected(bd_addr))  
  5.     {  
  6.         BTA_AgAudioOpen(btif_hf_cb.handle);  
  7.         /* Inform the application that the audio connection has been initiated successfully */  
  8.         btif_transfer_context(btif_in_hf_generic_evt, BTIF_HFP_CB_AUDIO_CONNECTING,  
  9.                               (char *)bd_addr, sizeof(bt_bdaddr_t), NULL);  
  10.         return BT_STATUS_SUCCESS;  
  11.     }  
  12.     return BT_STATUS_FAIL;  
  13. }  
 

 2. Connect Bluetooth headset in the Bluetooth list

     A2dp connection process, connect a Bluetooth headset in the Bluetooth list of search results, since it is starting from the device list, so this is a natural start of code
[java]  view plain copy
  1. DevicePickerFragment.java (settings\src\com\android\settings\bluetooth)     3884     2013-6-26  
  2.     void onClicked() {  
  3.       int bondState = mCachedDevice.getBondState();  
  4.       if (mCachedDevice.isConnected()) {  
  5.           askDisconnect();  
  6.       } else if (bondState == BluetoothDevice.BOND_BONDED) {  
  7.           mCachedDevice.connect(true);  
  8.       } .......  
  9.   }  
  10.   
  11.     void connect(boolean connectAllProfiles) {  
  12.       IF (! ensurePaired ()) {   // first make sure that pairing  
  13.           return;  
  14.       }  
  15.       mConnectAttempted = SystemClock.elapsedRealtime();  
  16.       connectWithoutResettingTimer (connectAllProfiles); // nothing else, only to see here  
  17.   }  
      Code path where packages / apps / Settings / src / com / android / settings / bluetooth / CachedBluetoothDevice.java, see the following specific code
[java]  view plain copy
  1. // Try to initialize the profiles if they were not.  
  2.      ...........  
  3.       // Reset the only-show-one-error-dialog tracking variable  
  4.       mIsConnectingErrorPossible = true;  
  5.   
  6.       int preferredProfiles = 0;  
  7.       for (LocalBluetoothProfile profile : mProfiles) {  
  8.           if (connectAllProfiles ? profile.isConnectable() : profile.isAutoConnectable()) {  
  9.               if (profile.isPreferred(mDevice)) {  
  10.                   ++preferredProfiles;  
  11.                   connectInt (Profile); // this connection,  
  12.               }  
  13.           }  
  14.       }  
  15.      .............  
       connectInt implementation is very simple, skip to see inside profile.connect (mDevice), profile here refers A2dpProfile, so the specific Connet () method is implemented in
[java]  view plain copy
  1. public boolean connect(BluetoothDevice device) {  
  2.     if (mService == null) return false;  
  3.     List<BluetoothDevice> sinks = getConnectedDevices();  
  4.     if (sinks != null) {  
  5.         for (BluetoothDevice sink : sinks) {  
  6.             mService.disconnect(sink);  
  7.     }}  
  8.     return mService.connect(device);  
  9. }  
        Here is BluetoothA2dp.java (frameworks \ base \ core \ java \ android \ bluetooth), why this is a look that private BluetoothA2dp mService; know
[java]  view plain copy
  1. public boolean connect(BluetoothDevice device) {  
  2.       if (mService != null && isEnabled() &&  
  3.           isValidDevice(device)) {  
  4.           try {  
  5.               return mService.connect(device);  
  6.           } catch (RemoteException e) {  
  7.               Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));  
  8.               return false;  
  9.           }  
  10.       }...........  
  11.       return false;  
  12.        
  13.       Binder Jump  
  14.       public boolean connect(BluetoothDevice device) {  
  15.           A2dpService service = getService();  
  16.           if (service == null) return false;  
  17.           return service.connect(device);  
  18.       }  
  19.        
  20.   }  
        After the first part of the jump and jump Bluetooth telephone answering similar process is not repeated, and finally will come to connectA2dpNative packages / apps / Bluetooth / jni / com_android_bluetooth_a2dp.cpp, the same to the code below, we can see the open the code is these, then look at the following specific vendor's true.
[java]  view plain copy
  1. static jboolean connectA2dpNative(JNIEnv *env, jobject object, jbyteArray address) {  
  2.   jbyte *addr;  
  3.   bt_bdaddr_t * btAddr;  
  4.   bt_status_t status;  
  5.   
  6.   ALOGI("%s: sBluetoothA2dpInterface: %p", __FUNCTION__, sBluetoothA2dpInterface);  
  7.   if (!sBluetoothA2dpInterface) return JNI_FALSE;  
  8.   
  9.   addr = env->GetByteArrayElements(address, NULL);  
  10.   btAddr = (bt_bdaddr_t *) addr;  
  11.   if (!addr) {  
  12.       jniThrowIOException (env, chosen);  
  13.       return JNI_FALSE;  
  14.   }  
  15.   if ((status = sBluetoothA2dpInterface->connect((bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {  
  16.       ALOGE("Failed HF connection, status: %d", status);  
  17.   }  
  18.   env->ReleaseByteArrayElements(address, addr, 0);  
  19.   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;  

Reproduced in: https: //www.cnblogs.com/wangzehuaw/p/3806774.html

Guess you like

Origin blog.csdn.net/weixin_34043301/article/details/93778420