蓝牙之十三-HFPclient JNI层

来源:互联网 发布:hough变换算法 编辑:程序博客网 时间:2024/06/06 07:26

JNI到app(JAVA)

<packages/apps/Bluetooth/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java>final class HeadsetClientStateMachine extends StateMachine {//静态块方法    static {        classInitNative();    }    private HeadsetClientStateMachine(HeadsetClientService context) {        initializeNative();    }    private native static void classInitNative();    private native void initializeNative();    private native void cleanupNative();    private native boolean connectNative(byte[] address);    private native boolean disconnectNative(byte[] address);    private native boolean connectAudioNative(byte[] address);    private native boolean disconnectAudioNative(byte[] address);、    private native boolean startVoiceRecognitionNative();    private native boolean stopVoiceRecognitionNative();    private native boolean setVolumeNative(int volumeType, int volume);    private native boolean dialNative(String number);    private native boolean dialMemoryNative(int location);    private native boolean handleCallActionNative(int action, int index);    private native boolean queryCurrentCallsNative();    private native boolean queryCurrentOperatorNameNative();    private native boolean retrieveSubscriberInfoNative();    private native boolean sendDtmfNative(byte code);    private native boolean requestLastVoiceTagNumberNative();    private native boolean sendATCmdNative(int ATCmd, int val1,            int val2, String arg);}
在如下文件会调用:
packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp:1199:    if ((status = android::register_com_android_bluetooth_hfpclient(e)) < 0) {
该方法的实现如下:
<packages/apps/Bluetooth/jni/com_android_bluetooth_hfpclient.cpp>static JNINativeMethod sMethods[] = {    {"classInitNative", "()V", (void *) classInitNative},    {"initializeNative", "()V", (void *) initializeNative},    {"cleanupNative", "()V", (void *) cleanupNative},    {"connectNative", "([B)Z", (void *) connectNative},    {"disconnectNative", "([B)Z", (void *) disconnectNative},    {"connectAudioNative", "([B)Z", (void *) connectAudioNative},    {"disconnectAudioNative", "([B)Z", (void *) disconnectAudioNative},    {"startVoiceRecognitionNative", "()Z", (void *) startVoiceRecognitionNative},    {"stopVoiceRecognitionNative", "()Z", (void *) stopVoiceRecognitionNative},    {"setVolumeNative", "(II)Z", (void *) setVolumeNative},    {"dialNative", "(Ljava/lang/String;)Z", (void *) dialNative},    {"dialMemoryNative", "(I)Z", (void *) dialMemoryNative},    {"handleCallActionNative", "(II)Z", (void *) handleCallActionNative},    {"queryCurrentCallsNative", "()Z", (void *) queryCurrentCallsNative},    {"queryCurrentOperatorNameNative", "()Z", (void *) queryCurrentOperatorNameNative},    {"retrieveSubscriberInfoNative", "()Z", (void *) retrieveSubscriberInfoNative},    {"sendDtmfNative", "(B)Z", (void *) sendDtmfNative},    {"requestLastVoiceTagNumberNative", "()Z",        (void *) requestLastVoiceTagNumberNative},    {"sendATCmdNative", "(IIILjava/lang/String;)Z", (void *) sendATCmdNative},};int register_com_android_bluetooth_hfpclient(JNIEnv* env){    return jniRegisterNativeMethods(env, "com/android/bluetooth/hfpclient/HeadsetClientStateMachine",                                    sMethods, NELEM(sMethods));}
该函数的作用是将com_android_bluetooth_hfpclient.cpp里的cpp函数注册以供java层调用。在开篇的文章的HeadsetClientStateMachine.java里调用了

静态块和构造函数里的方法在创建这个对象时会被执行。

static void classInitNative(JNIEnv* env, jclass clazz) {    method_onConnectionStateChanged = env->GetMethodID(clazz, "onConnectionStateChanged", "(III[B)V");    method_onAudioStateChanged = env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V");    method_onVrStateChanged = env->GetMethodID(clazz, "onVrStateChanged", "(I)V");    method_onNetworkState = env->GetMethodID(clazz, "onNetworkState", "(I)V");    method_onNetworkRoaming = env->GetMethodID(clazz, "onNetworkRoaming", "(I)V");    method_onNetworkSignal = env->GetMethodID(clazz, "onNetworkSignal", "(I)V");    method_onBatteryLevel = env->GetMethodID(clazz, "onBatteryLevel", "(I)V");    method_onCurrentOperator = env->GetMethodID(clazz, "onCurrentOperator", "(Ljava/lang/String;)V");    method_onCall = env->GetMethodID(clazz, "onCall", "(I)V");    method_onCallSetup = env->GetMethodID(clazz, "onCallSetup", "(I)V");    method_onCallHeld = env->GetMethodID(clazz, "onCallHeld", "(I)V");    method_onRespAndHold = env->GetMethodID(clazz, "onRespAndHold", "(I)V");    method_onClip = env->GetMethodID(clazz, "onClip", "(Ljava/lang/String;)V");    method_onCallWaiting = env->GetMethodID(clazz, "onCallWaiting", "(Ljava/lang/String;)V");    method_onCurrentCalls = env->GetMethodID(clazz, "onCurrentCalls", "(IIIILjava/lang/String;)V");    method_onVolumeChange = env->GetMethodID(clazz, "onVolumeChange", "(II)V");    method_onCmdResult = env->GetMethodID(clazz, "onCmdResult", "(II)V");    method_onSubscriberInfo = env->GetMethodID(clazz, "onSubscriberInfo", "(Ljava/lang/String;I)V");    method_onInBandRing = env->GetMethodID(clazz, "onInBandRing", "(I)V");    method_onLastVoiceTagNumber = env->GetMethodID(clazz, "onLastVoiceTagNumber",        "(Ljava/lang/String;)V");    method_onRingIndication = env->GetMethodID(clazz, "onRingIndication","()V");    ALOGI("%s succeeds", __FUNCTION__);}static void initializeNative(JNIEnv *env, jobject object) {    const bt_interface_t* btInf;    bt_status_t status;//检查Bluetooth 模块是否加载,HFP client依赖该模块被加载。    btInf = getBluetoothInterface();    if (btInf == NULL) {        ALOGE("Bluetooth module is not loaded");        return;    }    if (sBluetoothHfpClientInterface != NULL) {        ALOGW("Cleaning up Bluetooth HFP Client Interface before initializing");        sBluetoothHfpClientInterface->cleanup();        sBluetoothHfpClientInterface = NULL;    }    if (mCallbacksObj != NULL) {        ALOGW("Cleaning up Bluetooth HFP Client callback object");        env->DeleteGlobalRef(mCallbacksObj);        mCallbacksObj = NULL;    }    sBluetoothHfpClientInterface = (bthf_client_interface_t *)            btInf->get_profile_interface(BT_PROFILE_HANDSFREE_CLIENT_ID);    if (sBluetoothHfpClientInterface  == NULL) {        ALOGE("Failed to get Bluetooth HFP Client Interface");        return;    }    status = sBluetoothHfpClientInterface->init(&sBluetoothHfpClientCallbacks);    if (status != BT_STATUS_SUCCESS) {        ALOGE("Failed to initialize Bluetooth HFP Client, status: %d", status);        sBluetoothHfpClientInterface = NULL;        return;    }    mCallbacksObj = env->NewGlobalRef(object);}
这两个函数中,前一个函数在java类中查找了若干方法,这些方法被cpp函数调用,这里就是被com_android_bluetooth_hfpclient.cpp文件里的函数使用,这样就完成了java到cpp的映射。好了到这里就是JNI实现了JAVA到cpp和cpp到JAVA的函数映射关系。

JNI到协议栈(纯C)

在上面的第二个函数initializeNative实现了该功能。

<system/bt/btif/src/bluetooth.c>static const bt_interface_t bluetoothInterface = {    sizeof(bluetoothInterface),    init,    enable,    disable,    cleanup,    get_adapter_properties,    get_adapter_property,    set_adapter_property,    get_remote_device_properties,    get_remote_device_property,    set_remote_device_property,    get_remote_service_record,    get_remote_services,    start_discovery,    cancel_discovery,    create_bond,    remove_bond,    cancel_bond,    get_connection_state,    pin_reply,    ssp_reply,    get_profile_interface,    dut_mode_configure,    dut_mode_send,#if BLE_INCLUDED == TRUE    le_test_mode,#else    NULL,#endif    config_hci_snoop_log,    set_os_callouts,    read_energy_info,    dump,    config_clear};const bt_interface_t* bluetooth__get_bluetooth_interface (){    /* fixme -- add property to disable bt interface ? */    return &bluetoothInterface;} static int open_bluetooth_stack(const struct hw_module_t *module, UNUSED_ATTR char const *name, struct hw_device_t **abstraction) {  static bluetooth_device_t device = {    .common = {      .tag = HARDWARE_DEVICE_TAG,      .version = 0,      .close = close_bluetooth_stack,    },    .get_bluetooth_interface = bluetooth__get_bluetooth_interface  };  device.common.module = (struct hw_module_t *)module;  *abstraction = (struct hw_device_t *)&device;  return 0;}static struct hw_module_methods_t bt_stack_module_methods = {    .open = open_bluetooth_stack,};struct hw_module_t HAL_MODULE_INFO_SYM = {    .tag = HARDWARE_MODULE_TAG,    .version_major = 1,    .version_minor = 0,    .id = BT_HARDWARE_MODULE_ID,    .name = "Bluetooth Stack",    .author = "The Android Open Source Project",    .methods = &bt_stack_module_methods};
BT_HARDWARE_MODULE_ID定义于

<./hardware/libhardware/include/hardware/bluetooth.h>#define BT_HARDWARE_MODULE_ID "bluetooth"#define BT_STACK_MODULE_ID "bluetooth"#define BT_PROFILE_HANDSFREE_CLIENT_ID "handsfree_client"

状态机

/**19 * Bluetooth Headset Client StateMachine20 *                      (Disconnected)21 *                           | ^  ^22 *                   CONNECT | |  | DISCONNECTED23 *                           V |  |24 *                   (Connecting) |25 *                           |    |26 *                 CONNECTED |    | DISCONNECT27 *                           V    |28 *                        (Connected)29 *                           |    ^30 *             CONNECT_AUDIO |    | DISCONNECT_AUDIO31 *                           V    |32 *                         (AudioOn)33 */​

  状态机如上。有四个子类用于管理上述状态

 ​   private final Disconnected mDisconnected;    private final Connecting mConnecting;    private final Connected mConnected;    private final AudioOn mAudioOn;

 

BroadcastReceiver也就是“广播接收者”的意思,它是用来接收来自系统和应用中的广播。

  在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的 Broadcast进行过滤接受并响应的一类组件。

下面将详细的阐述如何发送Broadcast和使用BroadcastReceiver过滤接收的过程:

  (1)首先在需要发送信息的地方,把要发送的信息和用于过滤的信息(如Action、Category)装入一个Intent对象,然后通过调 用 sendOrderBroadcast()或sendStickyBroadcast()方法,把 Intent对象以广播方式发送出去。

  (2)当Intent发送以后,所有已经注册的BroadcastReceiver会检查注册时的IntentFilter是否与发送的 Intent相匹配,若匹配则就会调用BroadcastReceiver的onReceive()方法。所以当我们定义一个 BroadcastReceiver的时候,都需要实现onReceive()方法。

JNI实现回调

通过JNI在Native层调用JAVA层的方法,来实现Native层向JAVA层传递消息。

JNICallback.java

 ​public class JNICallback extends Activity {      static {          System.loadLibrary("callback");      }       public void callback(int notify_id, int param)      {          Log.e("JNICallback","notify_id="+notify_id+";param="+param);      }         public native void setCallBack();             /** Called when the activity is first created. */      @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.main);          setCallBack();      }  

com_JNICallback_JNICallback.cpp

 ​    void JNICALL Java_com_JNICallback_JNICallback_setCallBack        (JNIEnv *env, jobject obj)      {          LOGE("jni callback (0)");          jclass cls = env->GetObjectClass(obj);           jmethodID callback = env->GetMethodID(cls,"callback","(II)V");          env->CallVoidMethod(obj,callback,5,10);           LOGE("jni callback (1)");      }  

二、JNI调用JAVA函数

获取实例的类定义 jclass cls = env->GetObjectClass(obj);

获取方法定义  jmethodID callback = env->GetMethodID(cls,"callback","(II)V");

调用方法 env->CallVoidMethod(obj,callback,5,10);


三、参数和返回值的格式

0 0
原创粉丝点击