#include #include #include #include #include #include "securec.h" #include "softbus_bus_center.h" #include "session.h" #include "com_jg_softbus_naservice_SessionService.h" // 全局变量,用于保存Java虚拟机的引用 JavaVM *jvm; //全局引用变量sessionListener,用于保存java对象 jobject sessionListener; //全局引用变量fileSendListener,用于保存java对象 jobject fileSendListener; //全局引用变量fileReceiveListener,用于保存java对象 jobject fileReceiveListener; /** * sessionOpen */ int sessionOpened(int sessionId, int result) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, sessionListener); // 获取当前对象的onSessionOpened方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onSessionOpened", "(II)I"); // 调用当前对象的非静态方法 int ret = (*env)->CallIntMethod(env, sessionListener, callbackMethod, sessionId, result); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("sessionOpend: %d opened, result: %d.\n", sessionId, result); return ret; } /** * sessionClose */ void sessionClosed(int sessionId) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, sessionListener); // 获取当前对象的onSessionClosed方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onSessionClosed", "(I)V"); // 调用当前对象的非静态方法 (*env)->CallVoidMethod(env, sessionListener, callbackMethod, sessionId); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("sessionClosed: %d closed.\n", sessionId); } /** * 接收bytes数据 */ void bytesReceived(int sessionId, const void *data, unsigned int dataLen) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, sessionListener); // 获取当前对象的onBytesReceived方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onBytesReceived", "(I[BI)V"); //转换data为byte[]数组 jbyteArray byteArray = (*env)->NewByteArray(env, dataLen); jbyte *byteArrayElements = (*env)->GetByteArrayElements(env, byteArray, NULL); memcpy(byteArrayElements, data, dataLen); (*env)->ReleaseByteArrayElements(env, byteArray, byteArrayElements, 0); // 调用当前对象的非静态方法 (*env)->CallVoidMethod(env, sessionListener, callbackMethod, sessionId, byteArray, dataLen); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("bytesReceived: received data.\n"); } /** * 接收消息数据 */ void messageReceived(int sessionId, const void *data, unsigned int dataLen) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, sessionListener); // 获取当前对象的publishSuccess方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onMessageReceived", "(ILjava/lang/String;I)V"); //转换data为string const char *charData = (const char *)data; jstring jstr = (*env)->NewStringUTF(env, charData); // 调用当前对象的非静态方法 (*env)->CallVoidMethod(env, sessionListener, callbackMethod, sessionId, jstr, dataLen); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("messageReceived: received data:%s.\n", charData); } jobject parseStreamDataToJava(JNIEnv *env, const StreamData *data) { if(data == NULL) { return NULL; } //发现StreamData的java类 jclass streamDataClass = (*env)->FindClass(env, "com/jg/softbus/session/StreamData"); if (streamDataClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/session/StreamData"); return NULL; } //获取构造函数 jmethodID constructor = (*env)->GetMethodID(env, streamDataClass, "", "([BI)V"); if(constructor == NULL) { // 处理错误 printf("Cannot found the constructor(byte[], int):com/jg/softbus/session/StreamData"); return NULL; } //将data中的buf字符转换为java的byte数组 const char *charBuf = data->buf; jstring jstr = (*env)->NewStringUTF(env, charBuf); jsize len = (*env)->GetStringLength(env, jstr); jbyteArray byteArray = (*env)->NewByteArray(env, len); jboolean isCopy; jbyte *byteArrayElements = (*env)->GetByteArrayElements(env, byteArray, &isCopy); // 将 char *buf 复制到 jbyteArray 中 for (jsize i = 0; i < len; i++) { byteArrayElements[i] = (jbyte)charBuf[i]; } (*env)->ReleaseByteArrayElements(env, byteArray, byteArrayElements, 0); jobject obj = (*env)->NewObject(env, streamDataClass, constructor, byteArray, data->bufLen); (*env)->DeleteLocalRef(env, jstr); return obj; } /** * 解析StreamFrameInfo */ jobject parseStreamFrameInfoToJava(JNIEnv *env, const StreamFrameInfo *param) { if(param == NULL) { return NULL; } //发现StreamFrameInfo的java类 jclass streamFrameInfoClass = (*env)->FindClass(env, "com/jg/softbus/session/StreamFrameInfo"); if (streamFrameInfoClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/session/StreamFrameInfo"); return NULL; } //获取构造函数 jmethodID constructor = (*env)->GetMethodID(env, streamFrameInfoClass, "", "()V"); if(constructor == NULL) { // 处理错误 printf("Cannot found the constructor():com/jg/softbus/session/StreamFrameInfo"); return NULL; } jobject obj = (*env)->NewObject(env, streamFrameInfoClass, constructor); //获取setFrameType方法 jmethodID setFrameTypeMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setFrameType", "(I)V"); (*env)->CallVoidMethod(env, obj, setFrameTypeMethod, param->frameType); //获取setTimeStamp方法 jmethodID setTimeStampMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setTimeStamp", "(J)V"); (*env)->CallVoidMethod(env, obj, setTimeStampMethod, param->timeStamp); //setSeqNum jmethodID setSeqNumMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setSeqNum", "(I)V"); (*env)->CallVoidMethod(env, obj, setSeqNumMethod, param->seqNum); //setSeqSubNum jmethodID setSeqSubNumMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setSeqSubNum", "(I)V"); (*env)->CallVoidMethod(env, obj, setSeqSubNumMethod, param->seqSubNum); //setLevel jmethodID setLevelMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setLevel", "(I)V"); (*env)->CallVoidMethod(env, obj, setLevelMethod, param->level); //setBitMap jmethodID setBitMapMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setBitMap", "(I)V"); (*env)->CallVoidMethod(env, obj, setBitMapMethod, param->bitMap); //setTvCount jmethodID tvCountMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "tvCount", "(I)V"); (*env)->CallVoidMethod(env, obj, tvCountMethod, param->tvCount); //setTvList //还想TV类型对象 //发现StreamData的java类 jclass tvClass = (*env)->FindClass(env, "com/jg/softbus/session/TV"); if (tvClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/session/TV"); return obj; } //获取构造函数 jmethodID tvConstructor = (*env)->GetMethodID(env, tvClass, "", "([IJ)V"); if(constructor == NULL) { // 处理错误 printf("Cannot found the constructor(int, long):com/jg/softbus/session/TV"); return obj; } //构建一个TV类型的数组 jobjectArray tvArray = (*env)->NewObjectArray(env, param->tvCount, tvClass, NULL); for(int i=0; itvCount; i++) { jobject tvobject = (*env)->NewObject(env, tvClass, tvConstructor, param->tvList[i].type, param->tvList[i].value); (*env)->SetObjectArrayElement(env, tvArray, i, tvobject); (*env)->DeleteLocalRef(env, tvobject); } jmethodID setTvListMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setTvList", "(I)V"); (*env)->CallVoidMethod(env, obj, setTvListMethod, tvArray); (*env)->DeleteLocalRef(env, tvArray); return obj; } /** * 接收消息数据 */ void streamReceived(int sessionId, const StreamData *data, const StreamData *ext, const StreamFrameInfo *param) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, sessionListener); // 获取当前对象的onStreamReceived方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onStreamReceived", "(ILcom/jg/softbus/session/StreamData;Lcom/jg/softbus/session/StreamData;Lcom/jg/softbus/session/StreamFrameInfo;)V"); //转换data为string jobject streamData = parseStreamDataToJava(env, data); jobject extData = parseStreamDataToJava(env, ext); jobject streamframeInfo = parseStreamFrameInfoToJava(env, param); // 调用当前对象的非静态方法 (*env)->CallVoidMethod(env, sessionListener, callbackMethod, sessionId, streamData, extData, streamframeInfo); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("streamReceived\n"); } /** * 将c的WifiChannelQuality转换为java的对应对象 参见:com/jg/softbus/session/WifiChannelQuality */ jobject parseWifiChannelQualityToJava(JNIEnv *env, const QosTv *tv) { jclass wifiChannelQualityClass = (*env)->FindClass(env, "com/jg/softbus/session/WifiChannelQuality"); if (wifiChannelQualityClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/session/WifiChannelQuality"); return NULL; } //获取构造函数 jmethodID wifiChannelQualityConstructor = (*env)->GetMethodID(env, wifiChannelQualityClass, "", "(II)V"); if(wifiChannelQualityConstructor == NULL) { // 处理错误 printf("Cannot found the constructor():com/jg/softbus/session/WifiChannelQuality"); return NULL; } return (*env)->NewObject(env, wifiChannelQualityClass, wifiChannelQualityConstructor, tv->info.wifiChannelInfo.channel, tv->info.wifiChannelInfo.score); } /** * 将c的FrameStatus结构转换为java对象,参见:com/jg/softbus/session/FrameStatus */ jobject parseFrameStatusToJava(JNIEnv *env, const QosTv *tv) { jclass frameStatusClass = (*env)->FindClass(env, "com/jg/softbus/session/FrameStatus"); if (frameStatusClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/session/FrameStatus"); return NULL; } //获取构造函数 jmethodID frameStatusConstructor = (*env)->GetMethodID(env, frameStatusClass, "", "(IIIII)V"); if(frameStatusConstructor == NULL) { // 处理错误 printf("Cannot found the constructor():com/jg/softbus/session/FrameStatus"); return NULL; } return (*env)->NewObject(env, frameStatusClass, frameStatusConstructor, tv->info.frameStatusInfo.streamId, tv->info.frameStatusInfo.seqNum, tv->info.frameStatusInfo.level, tv->info.frameStatusInfo.transStatus, tv->info.frameStatusInfo.interval); } /** * 将c的BandwidthDetection结构转换为java对象 com/jg/softbus/session/BandwidthDetection */ jobject parseBandwidthDetectionToJava(JNIEnv *env, const QosTv *tv) { jclass bandwidthDetectionClass = (*env)->FindClass(env, "com/jg/softbus/session/BandwidthDetection"); if (bandwidthDetectionClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/session/BandwidthDetection"); return NULL; } //获取构造函数 jmethodID bandwidthDetectionConstructor = (*env)->GetMethodID(env, bandwidthDetectionClass, "", "(II)V"); if(bandwidthDetectionConstructor == NULL) { // 处理错误 printf("Cannot found the constructor():com/jg/softbus/session/BandwidthDetection"); return NULL; } return (*env)->NewObject(env, bandwidthDetectionClass, bandwidthDetectionConstructor, tv->info.bandwidthInfo.trend, tv->info.bandwidthInfo.rate); } /** * 将c的JitterEstimation结构转换为java对象 com/jg/softbus/session/JitterEstimation */ jobject parseJitterEstimationToJava(JNIEnv *env, const QosTv *tv) { jclass jitterEstimationClass = (*env)->FindClass(env, "com/jg/softbus/session/JitterEstimation"); if (jitterEstimationClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/session/JitterEstimation"); return NULL; } //获取构造函数 jmethodID jitterEstimationConstructor = (*env)->GetMethodID(env, jitterEstimationClass, "", "(II)V"); if(jitterEstimationConstructor == NULL) { // 处理错误 printf("Cannot found the constructor():com/jg/softbus/session/JitterEstimation"); return NULL; } return (*env)->NewObject(env, jitterEstimationClass, jitterEstimationConstructor, tv->info.jitterInfo.jitterLevel, tv->info.jitterInfo.bufferTime); } /** * 将c的StreamStatistics结构转换为java对象 com/jg/softbus/session/StreamStatistics */ jobject parseStreamStatisticsToJava(JNIEnv *env, const QosTv *tv) { jclass streamStatisticsClass = (*env)->FindClass(env, "com/jg/softbus/session/StreamStatistics"); if (streamStatisticsClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/session/StreamStatistics"); return NULL; } //获取构造函数 jmethodID streamStatisticsConstructor = (*env)->GetMethodID(env, streamStatisticsClass, "", "()V"); if(streamStatisticsConstructor == NULL) { // 处理错误 printf("Cannot found the constructor():com/jg/softbus/session/StreamStatistics"); return NULL; } jobject streamStatisticsObj = (*env)->NewObject(env, streamStatisticsClass, streamStatisticsConstructor); //setStatisticsGotTime jmethodID setStatisticsGotTimeMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setStatisticsGotTime", "(J)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setStatisticsGotTimeMethod, tv->info.appStatistics.statisticsGotTime); //setPeriodRecvBits jmethodID setPeriodRecvBitsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRecvBits", "(J)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRecvBitsMethod, tv->info.appStatistics.periodRecvBits); //setPktNum jmethodID setPktNumMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPktNum", "(I)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPktNumMethod, tv->info.appStatistics.pktNum); //setPeriodRecvPkts jmethodID setPeriodRecvPktsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRecvBits", "(I)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRecvPktsMethod, tv->info.appStatistics.periodRecvPkts); //setPeriodRecvPktLoss jmethodID setPeriodRecvPktLossMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRecvPktLoss", "(I)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRecvPktLossMethod, tv->info.appStatistics.periodRecvPktLoss); //setPeriodRecvRate jmethodID setPeriodRecvRateMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRecvRate", "(I)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRecvRateMethod, tv->info.appStatistics.periodRecvRate); //setPeriodRecvRateBps jmethodID setPeriodRecvRateBpsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRecvRateBps", "(J)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRecvRateBpsMethod, tv->info.appStatistics.periodRecvRateBps); //setPeriodRtt jmethodID setPeriodRttMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRtt", "(I)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRttMethod, tv->info.appStatistics.periodRtt); //setPeriodRecvPktLossHighPrecision jmethodID setPeriodRecvPktLossHighPrecisionMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRecvPktLossHighPrecision", "(I)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRecvPktLossHighPrecisionMethod, tv->info.appStatistics.periodRecvPktLossHighPrecision); //setPeriodSendLostPkts jmethodID setPeriodSendLostPktsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodSendLostPkts", "(I)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodSendLostPktsMethod, tv->info.appStatistics.periodSendLostPkts); //setPeriodSendPkts jmethodID setPeriodSendPktsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodSendPkts", "(I)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodSendPktsMethod, tv->info.appStatistics.periodSendPkts); //setPeriodSendPktLossHighPrecision jmethodID setPeriodSendPktLossHighPrecisionMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodSendPktLossHighPrecision", "(I)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodSendPktLossHighPrecisionMethod, tv->info.appStatistics.periodSendPktLossHighPrecision); //setPeriodSendBits jmethodID setPeriodSendBitsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodSendBits", "(J)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodSendBitsMethod, tv->info.appStatistics.periodSendBits); //setPeriodSendRateBps jmethodID setPeriodSendRateBpsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodSendRateBps", "(J)V"); (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodSendRateBpsMethod, tv->info.appStatistics.periodSendRateBps); return streamStatisticsObj; } /** * 将c的QosTvInfo结构转换为java对应的对象 */ jobject parseQosTvInfoToJava(JNIEnv *env, const QosTv *tv) { jclass qosTvInfoClass = (*env)->FindClass(env, "com/jg/softbus/session/QosTvInfo"); if (qosTvInfoClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/session/QosTvInfo"); return NULL; } //获取构造函数 jmethodID qosTvInfoConstructor = (*env)->GetMethodID(env, qosTvInfoClass, "", "()V"); if(qosTvInfoConstructor == NULL) { // 处理错误 printf("Cannot found the constructor():com/jg/softbus/session/QosTvInfo"); return NULL; } //创建qosTvInfo jobject qosTvInfoobject = (*env)->NewObject(env, qosTvInfoClass, qosTvInfoConstructor); //setWifiChannelInfo com/jg/softbus/session/WifiChannelQuality jobject wifiChannelQualityObj = parseWifiChannelQualityToJava(env, tv); jmethodID setWifiChannelInfoMethod = (*env)->GetMethodID(env, qosTvInfoClass, "setWifiChannelInfo", "(Lcom/jg/softbus/session/WifiChannelQuality;)V"); (*env)->CallVoidMethod(env, qosTvInfoobject, setWifiChannelInfoMethod, wifiChannelQualityObj); (*env)->DeleteLocalRef(env, wifiChannelQualityObj); //setFrameStatusInfo com/jg/softbus/session/FrameStatus jobject frameStatusObj = parseFrameStatusToJava(env, tv); jmethodID setFrameStatusInfoMethod = (*env)->GetMethodID(env, qosTvInfoClass, "setFrameStatusInfo", "(Lcom/jg/softbus/session/FrameStatus;)V"); (*env)->CallVoidMethod(env, qosTvInfoobject, setFrameStatusInfoMethod, frameStatusObj); (*env)->DeleteLocalRef(env, frameStatusObj); //setBandwidthInfo com/jg/softbus/session/BandwidthDetection jobject bandwidthDetectionObj = parseBandwidthDetectionToJava(env, tv); jmethodID setBandwidthInfoMethod = (*env)->GetMethodID(env, qosTvInfoClass, "setBandwidthInfo", "(Lcom/jg/softbus/session/BandwidthDetection;)V"); (*env)->CallVoidMethod(env, qosTvInfoobject, setBandwidthInfoMethod, bandwidthDetectionObj); (*env)->DeleteLocalRef(env, bandwidthDetectionObj); //setJitterInfo com/jg/softbus/session/JitterEstimation jobject jitterEstimationObj = parseJitterEstimationToJava(env, tv); jmethodID setJitterInfoMethod = (*env)->GetMethodID(env, qosTvInfoClass, "setJitterInfo", "(Lcom/jg/softbus/session/JitterEstimation;)V"); (*env)->CallVoidMethod(env, qosTvInfoobject, setJitterInfoMethod, jitterEstimationObj); (*env)->DeleteLocalRef(env, jitterEstimationObj); //setAppStatistics com/jg/softbus/session/StreamStatistics jobject streamStatisticsObj = parseStreamStatisticsToJava(env, tv); jmethodID setAppStatisticsMethod = (*env)->GetMethodID(env, qosTvInfoClass, "setAppStatistics", "(Lcom/jg/softbus/session/StreamStatistics;)V"); (*env)->CallVoidMethod(env, qosTvInfoobject, setAppStatisticsMethod, streamStatisticsObj); (*env)->DeleteLocalRef(env, streamStatisticsObj); return qosTvInfoobject; } /** * 将c的QosTv结构转换为java对应对象 */ jobject parseQosTvToJavaObject(JNIEnv *env, const QosTv *tv) { jclass qosTvClass = (*env)->FindClass(env, "com/jg/softbus/session/QosTv"); if (qosTvClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/session/QosTv"); return NULL; } //获取构造函数 jmethodID qosTvConstructor = (*env)->GetMethodID(env, qosTvClass, "", "()V"); if(qosTvConstructor == NULL) { // 处理错误 printf("Cannot found the constructor():com/jg/softbus/session/QosTv"); return NULL; } jobject tvobject = (*env)->NewObject(env, qosTvClass, qosTvConstructor); jclass transEnumEventTypeClass = (*env)->FindClass(env, "com/jg/softbus/session/enums/TransEnumEventType"); if (transEnumEventTypeClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/session/enums/TransEnumEventType"); return NULL; } jmethodID getForValueMethod = (*env)->GetStaticMethodID(env, transEnumEventTypeClass, "getForValue", "(I)Lcom/jg/softbus/session/enums/TransEnumEventType;"); if (getForValueMethod == NULL) { // 处理错误 printf("Cannot found the static method:getForValue(int)"); return NULL; } //setType jobject transEnumEventTypeObj = (*env)->CallStaticObjectMethod(env, transEnumEventTypeClass, getForValueMethod, tv->type); jmethodID setTypeMethod = (*env)->GetMethodID(env, qosTvClass, "setType", "(Lcom/jg/softbus/session/enums/TransEnumEventType;)V"); (*env)->CallVoidMethod(env, tvobject, setTypeMethod, transEnumEventTypeObj); (*env)->DeleteLocalRef(env, transEnumEventTypeObj); //setInfo com/jg/softbus/session/QosTvInfo jobject qosTvInfoobject = parseQosTvInfoToJava(env, tv); jmethodID setInfoMethod = (*env)->GetMethodID(env, qosTvClass, "setInfo", "(Lcom/jg/softbus/session/QosTvInfo;)V"); (*env)->CallVoidMethod(env, tvobject, setInfoMethod, qosTvInfoobject); (*env)->DeleteLocalRef(env, qosTvInfoobject); return tvobject; } /** * tvList */ jobjectArray parseQosTvListToJava(JNIEnv *env, int tvCount, const QosTv *tvList, jclass qosTvClass) { if(tvList == NULL) { return NULL; } //构建一个TV类型的数组 jobjectArray tvArray = (*env)->NewObjectArray(env, tvCount, qosTvClass, NULL); for(int i=0; iSetObjectArrayElement(env, tvArray, i, tvobject); (*env)->DeleteLocalRef(env, tvobject); } return tvArray; } /** * qosEvent */ void qosEvent(int sessionId, int eventId, int tvCount, const QosTv *tvList) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, sessionListener); // 获取当前对象的onQosEvent方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onQosEvent", "(III[Lcom/jg/softbus/session/QosTv;)V"); //转换data为string jobjectArray tvListArray = parseQosTvListToJava(env, tvCount, tvList, nativeLibClass); // 调用当前对象的非静态方法 (*env)->CallVoidMethod(env, sessionListener, callbackMethod, sessionId, eventId, tvCount, tvListArray); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("streamReceived\n"); } /* * Class: com_jg_softbus_naservice_SessionService * Method: createSessionServer * Signature: (Ljava/lang/String;Ljava/lang/String;Lcom/jg/softbus/session/callback/ISessionListener;)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_createSessionServer (JNIEnv *env, jobject obj, jstring pkgName, jstring sessionName, jobject listener) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); sessionListener = (*env)->NewGlobalRef(env, listener); //包名处理 const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL); const char *sessionNameStr = (*env)->GetStringUTFChars(env, sessionName, NULL); ISessionListener sl = { .OnSessionOpened = sessionOpened, .OnSessionClosed = sessionClosed, .OnBytesReceived = bytesReceived, .OnMessageReceived = messageReceived, .OnStreamReceived = streamReceived, .OnQosEvent = qosEvent }; printf("[jni] create session server..........\n"); int ret = CreateSessionServer(pkgNameStr, sessionNameStr, &sl); printf("[jni] create session server completed. the result: %d\n", ret); (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr); (*env)->ReleaseStringUTFChars(env, sessionName, sessionNameStr); return ret; } /** * 解析sessionAttribute */ int parseSessionAttribute(JNIEnv *env, jobject sessionAttr, SessionAttribute *attr) { if(sessionAttr == NULL) { return -1; } jclass sessionAttrClass = (*env)->GetObjectClass(env, sessionAttr); jmethodID getDataTypeMethod = (*env)->GetMethodID(env, sessionAttrClass, "getDataType", "()I"); jint dataType = (*env)->CallIntMethod(env, sessionAttr, getDataTypeMethod); attr->dataType = dataType; printf("SessionAttribute->dataType:%d\n", attr->dataType); jmethodID getLinkTypeNumMethod = (*env)->GetMethodID(env, sessionAttrClass, "getLinkTypeNum", "()I"); jint linkTypeNum = (*env)->CallIntMethod(env, sessionAttr, getLinkTypeNumMethod); attr->linkTypeNum = linkTypeNum; printf("SessionAttribute->linkTypeNum:%d\n", attr->linkTypeNum); //getLinkType linkType LinkType linkTypeEnum[linkTypeNum]; jmethodID getLinkTypeMethod = (*env)->GetMethodID(env, sessionAttrClass, "getLinkType", "()[Lcom/jg/softbus/session/enums/LinkType;"); jobjectArray linkTypes = (*env)->CallObjectMethod(env, sessionAttr, getLinkTypeMethod); jsize length = (*env)->GetArrayLength(env, linkTypes); for (jsize i = 0; i < length; i++) { jobject linkTypeObj = (*env)->GetObjectArrayElement(env, linkTypes, i); jclass linkTypeObjClass = (*env)->GetObjectClass(env, linkTypeObj); jmethodID getLinkTypeValueOfMethod = (*env)->GetMethodID(env, linkTypeObjClass, "valueOf", "()I"); jint linkTypeValue = (*env)->CallIntMethod(env, linkTypeObj, getLinkTypeValueOfMethod); linkTypeEnum[i] = (LinkType)linkTypeValue; printf("SessionAttribute->linkeType[%d]: %d\n", i, linkTypeEnum[i]); } memcpy(attr->linkType, linkTypeEnum, linkTypeNum); free(linkTypeEnum); //StreamAttr attr getAttr jmethodID getAttrMethod = (*env)->GetMethodID(env, sessionAttrClass, "getAttr", "()Lcom/jg/softbus/session/StreamAttr;"); jobject attrObj = (*env)->CallObjectMethod(env, sessionAttr, getAttrMethod); if(attrObj != NULL) { jclass attrObjClass = (*env)->GetObjectClass(env, attrObj); jmethodID getStreamTypeMethod = (*env)->GetMethodID(env, attrObjClass, "getStreamType", "()I"); jint streamType = (*env)->CallIntMethod(env, attrObj, getStreamTypeMethod); attr->attr.streamAttr.streamType = linkTypeNum; printf("attr->attr.streamAttr.streamType: %d", linkTypeNum); } //getFastTransData byte // jmethodID getFastTransDataMethod = (*env)->GetMethodID(env, sessionAttrClass, "getFastTransData", "()[B"); // jbyteArray fastTransData = (*env)->CallObjectMethod(env, sessionAttr, getFastTransDataMethod); // // 获取数组长度 // jsize fastTransDataLength = (*env)->GetArrayLength(fastTransData); // // 分配 uint8_t 数组 // uint8_t *transData[fastTransDataLength]; // // 将 jbyteArray 转换为 uint8_t 数组 // (*env)->GetByteArrayRegion(env, fastTransData, 0, length, (jbyte *) transData); // attr->fastTransData = transData; // free(transData); //getFastTransDataSize short // jmethodID getFastTransDataSizeMethod = (*env)->GetMethodID(env, sessionAttrClass, "getFastTransDataSize", "()S"); // jbyte transDataSize = (*env)->CallObjectMethod(env, sessionAttr, getFastTransDataSizeMethod); // attr->fastTransDataSize = transDataSize; return 0; } /* * Class: com_jg_softbus_naservice_SessionService * Method: openSession * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/jg/softbus/session/SessionAttribute;)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_openSession (JNIEnv *env, jobject obj, jstring sessionName, jstring peerSessionName, jstring peerNetworkId, jstring groupId, jobject sessionAttr) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); //包名处理 const char *sessionNameStr = (*env)->GetStringUTFChars(env, sessionName, NULL); const char *peerSessionNameStr = (*env)->GetStringUTFChars(env, peerSessionName, NULL); const char *peerNetworkIdStr = (*env)->GetStringUTFChars(env, peerNetworkId, NULL); const char *groupIdStr = (*env)->GetStringUTFChars(env, groupId, NULL); //转换SessionAttribute SessionAttribute attr; int ret = parseSessionAttribute(env, sessionAttr, &attr); if(ret != 0) { // 尝试进行一些可能会抛出异常的操作 jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类 // 如果找不到异常类,则抛出异常 jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "", "()V"); jthrowable exception = (*env)->NewObject(env,exceptionClass, exceptionConstructor); // 抛出异常 (*env)->ThrowNew(env, exceptionClass, "SessionAttribute object error."); //解析失败无法继续操作 return -1; } // 创建会话 ret = OpenSession(sessionNameStr, peerSessionNameStr, peerNetworkIdStr, groupIdStr, &attr); (*env)->ReleaseStringUTFChars(env, sessionName, sessionNameStr); (*env)->ReleaseStringUTFChars(env, peerSessionName, peerSessionNameStr); (*env)->ReleaseStringUTFChars(env, peerNetworkId, peerNetworkIdStr); (*env)->ReleaseStringUTFChars(env, groupId, groupIdStr); return ret; } /* * Class: com_jg_softbus_naservice_SessionService * Method: sendBytes * Signature: (ILjava/lang/String;)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_sendBytes (JNIEnv *env, jobject obj, jint sessionId, jbyteArray byteArray, jint len) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); jboolean isCopy; jbyte *byteArrayElements = (*env)->GetByteArrayElements(env, byteArray, &isCopy); if (byteArrayElements == NULL) { // 处理获取数组元素失败的情况 return -1; } // 将 jbyteArray 转换为 const void *data const void *data = byteArrayElements; (*env)->ReleaseByteArrayElements(env, byteArray, byteArrayElements, 0); return SendBytes(sessionId, data, len); } /* * Class: com_jg_softbus_naservice_SessionService * Method: sendMessage * Signature: (ILjava/lang/String;)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_sendMessage (JNIEnv *env, jobject obj, jint sessionId, jstring message, jint len) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); const char *charStr = (*env)->GetStringUTFChars(env, message, NULL); if (charStr == NULL) { // 处理内存分配失败的情况 (*env)->ReleaseStringUTFChars(env, message, charStr); return -1; } // 将 jstring 转换为 const void *data const void *data = (const void *)charStr; int ret = SendMessage(sessionId, data, len); (*env)->ReleaseStringUTFChars(env, message, charStr); return ret; } int parseStreamData(JNIEnv *env, jobject streamData, StreamData *data) { if(data == NULL) { return -1; } //获取StreamData的java类 jclass sessionAttrClass = (*env)->GetObjectClass(env, streamData); jmethodID getBufMethod = (*env)->GetMethodID(env, sessionAttrClass, "getBuf", "()[B"); jbyteArray byteArray = (*env)->CallObjectMethod(env, streamData, getBufMethod); jmethodID getBufLenMethod = (*env)->GetMethodID(env, sessionAttrClass, "getBufLen", "()I"); jint bufLen = (*env)->CallIntMethod(env, streamData, getBufLenMethod); data->bufLen = bufLen; char buf[bufLen]; // 将jbyteArray中的元素复制到char*类型的缓冲区中 (*env)->GetByteArrayRegion(env, byteArray, 0, bufLen, (jbyte*)buf); data->buf = buf; return 0; } /** * 解析streamframeinfo */ int parseStreamFrameInfo(JNIEnv *env, jobject param, StreamFrameInfo *data) { if(data == NULL) { return -1; } //获取StreamData的java类 jclass streamFrameInfoClass = (*env)->GetObjectClass(env, param); jmethodID getFrameTypeMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getFrameType", "()I"); jint frameType = (*env)->CallIntMethod(env, param, getFrameTypeMethod); data->frameType = frameType; jmethodID getTimeStampMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getTimeStamp", "()J"); jlong timeStamp = (*env)->CallLongMethod(env, param, getTimeStampMethod); data->timeStamp = (int64_t)timeStamp; jmethodID getSeqNumMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getSeqNum", "()I"); jint seqNum = (*env)->CallIntMethod(env, param, getSeqNumMethod); data->seqNum = seqNum; jmethodID getSeqSubNumMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getSeqSubNum", "()I"); jint seqSubNum = (*env)->CallIntMethod(env, param, getSeqSubNumMethod); data->seqSubNum = seqSubNum; jmethodID getLevelMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getLevel", "()I"); jint level = (*env)->CallIntMethod(env, param, getLevelMethod); data->level = level; jmethodID getBitMapMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getBitMap", "()I"); jint bitMap = (*env)->CallIntMethod(env, param, getBitMapMethod); data->bitMap = bitMap; jmethodID getTvCountMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getTvCount", "()I"); jint tvCount = (*env)->CallIntMethod(env, param, getTvCountMethod); data->tvCount = tvCount; jmethodID getTvListMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getTvList", "()Lcom/jg/softbus/session/TV;"); jobjectArray tvListArray = (*env)->CallObjectMethod(env, param, getTvListMethod); TV tvList[tvCount]; for(int i=0; iGetObjectArrayElement(env, tvListArray, i); if(tvObject != NULL) { jclass tvObjectClass = (*env)->GetObjectClass(env, tvObject); jmethodID tvGetTypeMethod = (*env)->GetMethodID(env, tvObjectClass, "getType", "()I"); jint tvType = (*env)->CallIntMethod(env, tvObject, tvGetTypeMethod); jmethodID tvGetValueMethod = (*env)->GetMethodID(env, tvObjectClass, "getValue", "()J"); jlong tvValue = (*env)->CallLongMethod(env, tvObject, tvGetValueMethod); tvList[i].type = (int)tvType; tvList[i].value = (int64_t)tvValue; } (*env)->DeleteLocalRef(env, tvObject); } data->tvList = tvList; } /* * Class: com_jg_softbus_naservice_SessionService * Method: sendStream * Signature: (ILcom/jg/softbus/session/StreamData;Lcom/jg/softbus/session/StreamData;Lcom/jg/softbus/session/StreamFrameInfo;)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_sendStream (JNIEnv *env, jobject obj, jint sessionId, jobject streamData, jobject ext, jobject param) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); StreamData data; int ret = parseStreamData(env, streamData, &data); if(ret != 0) { // 尝试进行一些可能会抛出异常的操作 jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类 // 如果找不到异常类,则抛出异常 jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "", "()V"); jthrowable exception = (*env)->NewObject(env,exceptionClass, exceptionConstructor); // 抛出异常 (*env)->ThrowNew(env, exceptionClass, "StreamData object error."); //解析失败无法继续操作 return -1; } StreamData extData; parseStreamData(env, ext, &extData); StreamFrameInfo sfi; parseStreamFrameInfo(env, param, &sfi); ret = SendStream(sessionId, &data, &extData, &sfi); return ret; } /* * Class: com_jg_softbus_naservice_SessionService * Method: sendFile * Signature: (I[Ljava/lang/String;[Ljava/lang/String;I)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_sendFile (JNIEnv *env, jobject obj, jint sessionId, jobjectArray sFileList, jobjectArray dFileList, jint fileCnt) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); // 获取数组长度 jsize sFileLen = (*env)->GetArrayLength(env, sFileList); const char *sFiles[sFileLen]; for(jsize i=0; i< sFileLen; i++) { jstring sFile = (*env)->GetObjectArrayElement(env, sFileList, i); const char *sFileStr = (*env)->GetStringUTFChars(env, sFile, NULL); sFiles[i] = sFileStr; (*env)->ReleaseStringUTFChars(env, sFile, sFileStr); (*env)->DeleteLocalRef(env, sFile); } jsize dFileLen = (*env)->GetArrayLength(env, dFileList); const char *dFiles[dFileLen]; for(jsize i=0; i< dFileLen; i++) { jstring dFile = (*env)->GetObjectArrayElement(env, dFileList, i); const char *dFileStr = (*env)->GetStringUTFChars(env, dFile, NULL); dFiles[i] = dFileStr; (*env)->ReleaseStringUTFChars(env, dFile, dFileStr); (*env)->DeleteLocalRef(env, dFile); } return SendFile(sessionId, sFiles, dFiles, fileCnt); } /** * 发送进度回调 */ int sendFileProcess(int sessionId, uint64_t bytesUpload, uint64_t bytesTotal) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, fileSendListener); // 获取当前对象的onQosEvent方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onSendFileProcess", "(IJJ)I"); // 调用当前对象的非静态方法 jint ret = (*env)->CallIntMethod(env, fileSendListener, callbackMethod, sessionId, bytesUpload, bytesTotal); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("sendFileProcess, sessionId:%d, send bytes:%d\n", sessionId, bytesUpload); return ret; } /** * 发送完成回调 */ int sendFileFinished(int sessionId, const char *firstFile) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, fileSendListener); // 获取当前对象的onQosEvent方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onSendFileFinished", "(ILjava/lang/String;)I"); jstring firstFileStr = (*env)->NewStringUTF(env, firstFile); // 调用当前对象的非静态方法 jint ret = (*env)->CallIntMethod(env, fileSendListener, callbackMethod, sessionId, firstFileStr); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("sendFileFinished, sessionId:%d, firstFile:%s\n", sessionId, firstFile); return ret; } /** * 发送报错 */ void sendFileTransError(int sessionId) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, fileSendListener); // 获取当前对象的onQosEvent方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onFileTransError", "(I)V"); // 调用当前对象的非静态方法 (*env)->CallVoidMethod(env, fileSendListener, callbackMethod, sessionId); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("sendFileTransError, sessionId:%d\n", sessionId); } /* * Class: com_jg_softbus_naservice_SessionService * Method: setFileSendListener * Signature: (Ljava/lang/String;Ljava/lang/String;Lcom/jg/softbus/session/callback/IFileSendListener;)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_setFileSendListener (JNIEnv *env, jobject obj, jstring pkgName, jstring sessionName, jobject listener) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); fileSendListener = (*env)->NewGlobalRef(env, listener); //包名处理 const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL); const char *sessionNameStr = (*env)->GetStringUTFChars(env, sessionName, NULL); IFileSendListener fsl = { .OnSendFileProcess = sendFileProcess, .OnSendFileFinished = sendFileFinished, .OnFileTransError = sendFileTransError }; int ret = SetFileSendListener(pkgNameStr, sessionNameStr, &fsl); (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr); (*env)->ReleaseStringUTFChars(env, sessionName, sessionNameStr); return ret; } /** * 开始接收回调 */ int receiveFileStarted(int sessionId, const char *files, int fileCnt) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, fileReceiveListener); // 获取当前对象的onQosEvent方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onReceiveFileStarted", "(ILjava/lang/String;I)I"); jstring filesStr = (*env)->NewStringUTF(env, files); // 调用当前对象的非静态方法 jint ret = (*env)->CallIntMethod(env, fileReceiveListener, callbackMethod, sessionId, filesStr, fileCnt); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("receiveFileProcess, sessionId:%d, files:%s, fileCnt: %d\n", sessionId, files, fileCnt); return ret; } /** * 接收进度回调 */ int receiveFileProcess(int sessionId, const char *firstFile, uint64_t bytesUpload, uint64_t bytesTotal) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, fileReceiveListener); // 获取当前对象的onQosEvent方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onReceiveFileProcess", "(ILjava/lang/String;JJ)I"); jstring firstFileStr = (*env)->NewStringUTF(env, firstFile); // 调用当前对象的非静态方法 jint ret = (*env)->CallIntMethod(env, fileReceiveListener, callbackMethod, sessionId, firstFileStr, bytesUpload, bytesTotal); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("receiveFileProcess, sessionId:%d, firstFile:%s, bytesUpload: %d, bytesTotal: %d\n", sessionId, firstFile, bytesUpload, bytesTotal); return ret; } /** * 接收文件完成回调 */ void receiveFileFinished(int sessionId, const char *files, int fileCnt) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, fileReceiveListener); // 获取当前对象的onQosEvent方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onReceiveFileFinished", "(ILjava/lang/String;I)V"); jstring filesStr = (*env)->NewStringUTF(env, files); // 调用当前对象的非静态方法 (*env)->CallVoidMethod(env, fileReceiveListener, callbackMethod, sessionId, filesStr, fileCnt); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("receiveFileFinished, sessionId:%d, files:%s, fileCnt: %d\n", sessionId, files, fileCnt); } /** * 接收错误回调 */ void receiveFileTransError(int sessionId) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, fileReceiveListener); // 获取当前对象的onQosEvent方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onFileTransError", "(I)V"); // 调用当前对象的非静态方法 (*env)->CallVoidMethod(env, fileReceiveListener, callbackMethod, sessionId); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("receiveFileTransError, sessionId:%d\n", sessionId); } /* * Class: com_jg_softbus_naservice_SessionService * Method: setFileReceiveListener * Signature: (Ljava/lang/String;Ljava/lang/String;Lcom/jg/softbus/session/callback/IFileReceiveListener;Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_setFileReceiveListener (JNIEnv *env, jobject obj, jstring pkgName, jstring sessionName, jobject listener, jstring rootDir) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); fileReceiveListener = (*env)->NewGlobalRef(env, listener); //包名处理 const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL); const char *sessionNameStr = (*env)->GetStringUTFChars(env, sessionName, NULL); const char *rootDirStr = (*env)->GetStringUTFChars(env, rootDir, NULL); IFileReceiveListener frl = { .OnReceiveFileStarted = receiveFileStarted, .OnReceiveFileProcess = receiveFileProcess, .OnReceiveFileFinished = receiveFileFinished, .OnFileTransError = receiveFileTransError }; int ret = SetFileReceiveListener(pkgNameStr, sessionNameStr, &frl, rootDirStr); (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr); (*env)->ReleaseStringUTFChars(env, sessionName, sessionNameStr); (*env)->ReleaseStringUTFChars(env, rootDir, rootDirStr); return ret; } /* * Class: com_jg_softbus_naservice_SessionService * Method: closeSession * Signature: (I)V */ JNIEXPORT void JNICALL Java_com_jg_softbus_naservice_SessionService_closeSession (JNIEnv *env, jobject obj, jint sessionId) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); CloseSession(sessionId); } /* * Class: com_jg_softbus_naservice_SessionService * Method: removeSessionServer * Signature: (Ljava/lang/String;Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_removeSessionServer (JNIEnv *env, jobject obj, jstring pkgName, jstring sessionName) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL); const char *sessionNameStr = (*env)->GetStringUTFChars(env, sessionName, NULL); printf("[jni]: remove session....\n"); int ret = RemoveSessionServer(pkgNameStr, sessionNameStr); printf("[jni]: remove session completed. the result: %d\n", ret); (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr); (*env)->ReleaseStringUTFChars(env, sessionName, sessionNameStr); return ret; } JNIEXPORT jstring JNICALL Java_com_jg_softbus_naservice_SessionService_getPeerDeviceId (JNIEnv *env, jobject obj, jint sessionId) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); char *networkId = "default"; int ret = GetPeerDeviceId(sessionId, networkId, NETWORK_ID_BUF_LEN); if(networkId != NULL){ jstring networkIdStr = (*env)->NewStringUTF(env, networkId); return networkIdStr; } return NULL; } /* * Class: com_jg_softbus_naservice_SessionService * Method: getPeerSessionName * Signature: (I)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_jg_softbus_naservice_SessionService_getPeerSessionName (JNIEnv *env, jobject obj, jint sessionId) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); char *sessionName = "default"; int ret = GetPeerSessionName(sessionId, sessionName, 255); if(sessionName != NULL){ jstring sessionNameStr = (*env)->NewStringUTF(env, sessionName); return sessionNameStr; } return NULL; } JNIEXPORT void JNICALL Java_com_jg_softbus_naservice_SessionService_destroy (JNIEnv *env, jobject obj) { printf("[session]destory the session data.\r\n"); // 删除全局引用 (*env)->DeleteGlobalRef(env, sessionListener); printf("[session]sessionListener have been destory.\r\n"); (*env)->DeleteGlobalRef(env, fileSendListener); printf("[session]fileSendListener have been destory.\r\n"); (*env)->DeleteGlobalRef(env, fileReceiveListener); printf("[session]fileReceiveListener have been destory.\r\n"); // if(jvm != NULL) { // free(jvm); // printf("[session]jvm have been destory.\r\n"); // } }