From def3a31e09e2f9397a9a9c11ce366158df74e657 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 12 Oct 2017 13:05:38 +0200 Subject: [PATCH] Do not wrap IMEE + fix java wrapper compil when using -j + fixed classBl in abstractAPI tool + various fixes for jni layer of java wrapper --- coreapi/CMakeLists.txt | 4 +- include/linphone/api/c-chat-room.h | 1 + include/linphone/im_encryption_engine.h | 24 +++++++ tools/abstractapi.py | 4 +- wrappers/java/genwrapper.py | 79 ++++++++++++++++------- wrappers/java/jni.mustache | 84 ++++++++++++++----------- 6 files changed, 133 insertions(+), 63 deletions(-) diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index d4faf04cc..6065c4a8f 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -206,9 +206,6 @@ if(ENABLE_STATIC) add_dependencies(linphone-static liblinphone-git-version) target_include_directories(linphone-static PUBLIC ${LINPHONE_INCLUDE_DIRS}) target_link_libraries(linphone-static INTERFACE ${LIBS}) - if(ANDROID) - add_dependencies(linphone-static linphonecore-jni-header) - endif() if(IOS) target_link_libraries(linphone-static INTERFACE "-framework Foundation" "-framework AVFoundation") endif() @@ -254,6 +251,7 @@ if(ENABLE_SHARED) set_target_properties(linphone PROPERTIES PREFIX "lib") elseif(ANDROID) target_link_libraries(linphone PUBLIC "log" ${SUPPORT_LIBRARIES} ${CPUFEATURES_LIBRARIES}) + add_dependencies(linphone linphonej) endif() if(MSVC) if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") diff --git a/include/linphone/api/c-chat-room.h b/include/linphone/api/c-chat-room.h index e6e1d0d31..534c4265e 100644 --- a/include/linphone/api/c-chat-room.h +++ b/include/linphone/api/c-chat-room.h @@ -78,6 +78,7 @@ LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message(LinphoneC * @param is_read TRUE if the message should be flagged as read, FALSE otherwise. * @param is_incoming TRUE if the message has been received, FALSE otherwise. * @return a new #LinphoneChatMessage + * @donotwrap */ LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message_2(LinphoneChatRoom *cr, const char* message, const char* external_body_url, LinphoneChatMessageState state, time_t time, bool_t is_read, bool_t is_incoming); diff --git a/include/linphone/im_encryption_engine.h b/include/linphone/im_encryption_engine.h index d4c15dc3d..2a39661a9 100644 --- a/include/linphone/im_encryption_engine.h +++ b/include/linphone/im_encryption_engine.h @@ -35,12 +35,14 @@ extern "C" { * Acquire a reference to the LinphoneImEncryptionEngineCbs. * @param[in] cbs LinphoneImEncryptionEngineCbs object. * @return The same LinphoneImEncryptionEngineCbs object. + * @donotwrap **/ LinphoneImEncryptionEngineCbs * linphone_im_encryption_engine_cbs_ref(LinphoneImEncryptionEngineCbs *cbs); /** * Release reference to the LinphoneImEncryptionEngineCbs. * @param[in] cbs LinphoneImEncryptionEngineCbs object. + * @donotwrap **/ void linphone_im_encryption_engine_cbs_unref(LinphoneImEncryptionEngineCbs *cbs); @@ -48,6 +50,7 @@ void linphone_im_encryption_engine_cbs_unref(LinphoneImEncryptionEngineCbs *cbs) * Gets the user data in the LinphoneImEncryptionEngineCbs object * @param[in] cbs the LinphoneImEncryptionEngineCbs * @return the user data + * @donotwrap */ LINPHONE_PUBLIC void *linphone_im_encryption_engine_cbs_get_user_data(const LinphoneImEncryptionEngineCbs *cbs); @@ -55,6 +58,7 @@ LINPHONE_PUBLIC void *linphone_im_encryption_engine_cbs_get_user_data(const Linp * Sets the user data in the LinphoneImEncryptionEngineCbs object * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @param[in] data the user data + * @donotwrap */ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_user_data(LinphoneImEncryptionEngineCbs *cbs, void *data); @@ -62,12 +66,14 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_user_data(LinphoneImE * Acquire a reference to the LinphoneImEncryptionEngine. * @param[in] imee LinphoneImEncryptionEngine object. * @return The same LinphoneImEncryptionEngine object. + * @donotwrap **/ LINPHONE_PUBLIC LinphoneImEncryptionEngine * linphone_im_encryption_engine_ref(LinphoneImEncryptionEngine *imee); /** * Release reference to the LinphoneImEncryptionEngine. * @param[in] imee LinphoneImEncryptionEngine object. + * @donotwrap **/ LINPHONE_PUBLIC void linphone_im_encryption_engine_unref(LinphoneImEncryptionEngine *imee); @@ -75,6 +81,7 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_unref(LinphoneImEncryptionEng * Gets the user data in the LinphoneImEncryptionEngine object * @param[in] imee the LinphoneImEncryptionEngine * @return the user data + * @donotwrap */ LINPHONE_PUBLIC void *linphone_im_encryption_engine_get_user_data(const LinphoneImEncryptionEngine *imee); @@ -82,6 +89,7 @@ LINPHONE_PUBLIC void *linphone_im_encryption_engine_get_user_data(const Linphone * Sets the user data in the LinphoneImEncryptionEngine object * @param[in] imee the LinphoneImEncryptionEngine object * @param[in] data the user data + * @donotwrap */ LINPHONE_PUBLIC void linphone_im_encryption_engine_set_user_data(LinphoneImEncryptionEngine *imee, void *data); @@ -89,6 +97,7 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_set_user_data(LinphoneImEncry * Gets the LinphoneCore object that created the IM encryption engine * @param[in] imee LinphoneImEncryptionEngine object * @return The LinphoneCore object that created the IM encryption engine + * @donotwrap */ LINPHONE_PUBLIC LinphoneCore * linphone_im_encryption_engine_get_core(LinphoneImEncryptionEngine *imee); @@ -96,6 +105,7 @@ LINPHONE_PUBLIC LinphoneCore * linphone_im_encryption_engine_get_core(LinphoneIm * Gets the LinphoneImEncryptionEngineCbs object that holds the callbacks * @param[in] imee the LinphoneImEncryptionEngine object * @return the LinphoneImEncryptionEngineCbs object + * @donotwrap */ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbs* linphone_im_encryption_engine_get_callbacks(const LinphoneImEncryptionEngine *imee); @@ -103,6 +113,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbs* linphone_im_encryption_engine_get * Gets the callback that will decrypt the chat messages upon reception * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @return the callback + * @donotwrap */ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsIncomingMessageCb linphone_im_encryption_engine_cbs_get_process_incoming_message(LinphoneImEncryptionEngineCbs *cbs); @@ -110,6 +121,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsIncomingMessageCb linphone_im_encry * Sets the callback that will decrypt the chat messages upon reception * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @param[in] cb the callback to call + * @donotwrap */ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_incoming_message(LinphoneImEncryptionEngineCbs *cbs, LinphoneImEncryptionEngineCbsIncomingMessageCb cb); @@ -117,6 +129,7 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_incoming_mess * Gets the callback that will encrypt the chat messages before sending them * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @return the callback + * @donotwrap */ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsOutgoingMessageCb linphone_im_encryption_engine_cbs_get_process_outgoing_message(LinphoneImEncryptionEngineCbs *cbs); @@ -124,6 +137,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsOutgoingMessageCb linphone_im_encry * Sets the callback that will encrypt the chat messages before sending them * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @param[in] cb the callback to call + * @donotwrap */ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_outgoing_message(LinphoneImEncryptionEngineCbs *cbs, LinphoneImEncryptionEngineCbsOutgoingMessageCb cb); @@ -131,6 +145,7 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_outgoing_mess * Gets the callback that will decrypt the files while downloading them * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @return the callback + * @donotwrap */ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsDownloadingFileCb linphone_im_encryption_engine_cbs_get_process_downloading_file(LinphoneImEncryptionEngineCbs *cbs); @@ -138,6 +153,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsDownloadingFileCb linphone_im_encry * Sets the callback that will decrypt the files while downloading them * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @param[in] cb the callback to call + * @donotwrap */ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_downloading_file(LinphoneImEncryptionEngineCbs *cbs, LinphoneImEncryptionEngineCbsDownloadingFileCb cb); @@ -145,6 +161,7 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_downloading_f * Gets the callback that will will encrypt the files while uploading them * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @return the callback + * @donotwrap */ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsUploadingFileCb linphone_im_encryption_engine_cbs_get_process_uploading_file(LinphoneImEncryptionEngineCbs *cbs); @@ -152,6 +169,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsUploadingFileCb linphone_im_encrypt * Sets the callback that will encrypt the files while uploading them * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @param[in] cb the callback to call + * @donotwrap */ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_uploading_file(LinphoneImEncryptionEngineCbs *cbs, LinphoneImEncryptionEngineCbsUploadingFileCb cb); @@ -159,6 +177,7 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_uploading_fil * Gets the callback telling wheter or not to encrypt the files * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @return the callback + * @donotwrap */ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsIsEncryptionEnabledForFileTransferCb linphone_im_encryption_engine_cbs_get_is_encryption_enabled_for_file_transfer(LinphoneImEncryptionEngineCbs *cbs); @@ -166,6 +185,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsIsEncryptionEnabledForFileTransferC * Sets the callback telling wheter or not to encrypt the files * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @param[in] cb the callback to call + * @donotwrap */ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_is_encryption_enabled_for_file_transfer(LinphoneImEncryptionEngineCbs *cbs, LinphoneImEncryptionEngineCbsIsEncryptionEnabledForFileTransferCb cb); @@ -173,6 +193,7 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_is_encryption_enabled * Gets the callback that will generate the key to encrypt the file before uploading it * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @return the callback + * @donotwrap */ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb linphone_im_encryption_engine_cbs_get_generate_file_transfer_key(LinphoneImEncryptionEngineCbs *cbs); @@ -180,6 +201,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb linphone_ * Sets the callback that will generate the key to encrypt the file before uploading it * @param[in] cbs the LinphoneImEncryptionEngineCbs object * @param[in] cb the callback to call + * @donotwrap */ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_generate_file_transfer_key(LinphoneImEncryptionEngineCbs *cbs, LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb cb); @@ -187,12 +209,14 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_generate_file_transfe * @param[in] msg LinphoneChatMessage * @param[in] text Const char * * @returns 0 if succeed. + * @donotwrap */ LINPHONE_PUBLIC int linphone_chat_message_set_text(LinphoneChatMessage *msg, const char* text); /** * Create the IM encryption engine * @return The created the IM encryption engine + * @donotwrap */ LINPHONE_PUBLIC LinphoneImEncryptionEngine *linphone_im_encryption_engine_new(void); diff --git a/tools/abstractapi.py b/tools/abstractapi.py index 00ab7d076..d7010dbb0 100644 --- a/tools/abstractapi.py +++ b/tools/abstractapi.py @@ -446,7 +446,7 @@ class Interface(DocumentableObject): class CParser(object): - def __init__(self, cProject): + def __init__(self, cProject, classBlAppend=[]): self.cBaseType = ['void', 'bool_t', 'char', 'short', 'int', 'long', 'size_t', 'time_t', 'float', 'double', 'LinphoneStatus'] self.cListType = 'bctbx_list_t' self.regexFixedSizeInteger = '^(u?)int(\d?\d)_t$' @@ -457,6 +457,8 @@ class CParser(object): 'linphone_vcard_get_belcard'] # manualy wrapped self.classBl = ['LpConfig'] # temporarly blacklisted + for bl in classBlAppend: + self.classBl.append(bl) # list of classes that must be concidered as refcountable even if # they are no ref()/unref() methods diff --git a/wrappers/java/genwrapper.py b/wrappers/java/genwrapper.py index 180aa4c9d..749c4889e 100644 --- a/wrappers/java/genwrapper.py +++ b/wrappers/java/genwrapper.py @@ -116,11 +116,21 @@ class JavaTranslator(object): return 'V' return _type - def translate_as_c_base_type(self, _type): + def translate_as_c_base_type(self, t): + _type = t.name if _type == 'string': - return 'const char *' + return 'char *' elif _type == 'integer': - return 'int' + if t.size is None: + if t.isUnsigned: + return 'unsigned int' + return 'int' + inttype = 'int{0}_t'.format(t.size) + if t.isUnsigned: + inttype = 'u' + inttype + if t.isref: + inttype = inttype + ' *' + return inttype elif _type == 'boolean': return 'bool_t' elif _type == 'floatant': @@ -132,11 +142,13 @@ class JavaTranslator(object): elif _type == 'status': return 'int' elif _type == 'string_array': - return 'const char **' + return 'char **' elif _type == 'character': return 'char' elif _type == 'void': - return 'void *' + if t.isref: + return 'void *' + return 'void' return _type def translate_type(self, _type, native=False, jni=False, isReturn=False): @@ -145,6 +157,8 @@ class JavaTranslator(object): if type(_type.containedTypeDesc) is AbsApi.ClassType: return 'jobjectArray' elif type(_type.containedTypeDesc) is AbsApi.BaseType: + if _type.containedTypeDesc.name == 'string': + return 'jobjectArray' return self.translate_type(_type.containedTypeDesc, jni=True) + 'Array' elif type(_type.containedTypeDesc) is AbsApi.EnumType: ptrtype = self.translate_type(_type.containedTypeDesc, native) @@ -322,7 +336,8 @@ class JavaTranslator(object): methodDict['return'] = self.translate_type(_method.returnType, jni=True, isReturn=True) methodDict['hasListReturn'] = methodDict['return'] == 'jobjectArray' methodDict['hasReturn'] = not methodDict['return'] == 'void' and not methodDict['hasListReturn'] - methodDict['hasNormalReturn'] = not methodDict['hasListReturn'] + methodDict['hasStringReturn'] = methodDict['return'] == 'jstring' + methodDict['hasNormalReturn'] = not methodDict['hasListReturn'] and not methodDict['hasStringReturn'] methodDict['name'] = 'Java_' + self.jni_package + className.to_camel_case() + 'Impl_' + _method.name.to_camel_case(lower=True) methodDict['notStatic'] = not static methodDict['c_name'] = 'linphone_' + className.to_snake_case() + "_" + _method.name.to_snake_case() @@ -332,7 +347,9 @@ class JavaTranslator(object): methodDict['isStringObjectArray'] = False if methodDict['hasListReturn']: - if _method.returnType.name == 'string_array': + if type(_method.returnType) is AbsApi.BaseType and _method.returnType.name == 'string_array': + methodDict['isStringObjectArray'] = True + elif type(_method.returnType.containedTypeDesc) is AbsApi.BaseType: methodDict['isStringObjectArray'] = True elif type(_method.returnType.containedTypeDesc) is AbsApi.ClassType: methodDict['isRealObjectArray'] = True @@ -340,8 +357,6 @@ class JavaTranslator(object): methodDict['objectClassCName'] = 'Linphone' + _method.returnType.containedTypeDesc.desc.name.to_camel_case() methodDict['objectClassName'] = _method.returnType.containedTypeDesc.desc.name.to_camel_case() methodDict['objectClassImplName'] = _method.returnType.containedTypeDesc.desc.name.to_camel_case() + 'Impl' - else: - print 'toto' methodDict['params'] = 'JNIEnv *env, jobject thiz' if static else 'JNIEnv *env, jobject thiz, jlong ptr' methodDict['params_impl'] = '' @@ -352,18 +367,26 @@ class JavaTranslator(object): methodDict['returnedObjectGetter'] = '' for arg in _method.args: methodDict['params'] += ', ' - methodDict['params_impl'] += ', ' + if static: + if arg is not _method.args[0]: + methodDict['params_impl'] += ', ' + else: + methodDict['params_impl'] += ', ' + methodDict['params'] += self.translate_argument(arg, jni=True) argname = self.translate_argument_name(arg.name) if type(arg.type) is AbsApi.ClassType: - methodDict['objects'].append({'object': argname, 'objectClassCName': 'Linphone' + arg.type.desc.name.to_camel_case()}) + classCName = 'Linphone' + arg.type.desc.name.to_camel_case() + if classCName[-8:] == 'Listener': + classCName = 'Linphone' + arg.type.desc.name.to_camel_case()[:-8] + 'Cbs' + methodDict['objects'].append({'object': argname, 'objectClassCName': classCName}) methodDict['params_impl'] += 'c_' + argname elif type(arg.type) is AbsApi.ListType: isStringList = type(arg.type.containedTypeDesc) is AbsApi.BaseType and arg.type.containedTypeDesc.name == 'string' isObjList = type(arg.type.containedTypeDesc) is AbsApi.ClassType - methodDict['lists'].append({'list': argname, 'isStringList': isStringList, 'isObjList': isObjList}) + methodDict['lists'].append({'list': argname, 'isStringList': isStringList, 'isObjList': isObjList, 'objectClassCName': arg.type.containedTypeDesc.name}) methodDict['params_impl'] += 'bctbx_list_' + argname elif type(arg.type) is AbsApi.EnumType: @@ -375,7 +398,7 @@ class JavaTranslator(object): methodDict['strings'].append({'string': argname}) methodDict['params_impl'] += 'c_' + argname else: - methodDict['params_impl'] += argname + methodDict['params_impl'] += '(' + self.translate_as_c_base_type(arg.type) + ')' + argname else: methodDict['params_impl'] += argname @@ -434,14 +457,18 @@ class JavaTranslator(object): methodDict['className'] = className.to_camel_case() methodDict['classImplName'] = className.to_camel_case() + 'Impl' methodDict['jniPath'] = self.jni_path - methodDict['cPrefix'] = 'linphone_' + className.to_snake_case() + methodDict['cPrefix'] = 'linphone_' + className.to_snake_case()[:-9] # Remove _listener at the end methodDict['callbackName'] = methodDict['cPrefix'] + '_' + _method.name.to_snake_case() methodDict['jname'] = _method.name.to_camel_case(lower=True) - methodDict['return'] = self.translate_type(_method.returnType, jni=True, isReturn=True) - + methodDict['return'] = self.translate_as_c_base_type(_method.returnType) + if type(_method.returnType) is AbsApi.ClassType: + methodDict['return'] += '*' + methodDict['returnIfFail'] = '' if methodDict['return'] == 'void' else ' NULL' #TODO + methodDict['hasReturn'] = not methodDict['return'] == 'void' methodDict['isSingleListener'] = not _class.multilistener methodDict['isMultiListener'] = _class.multilistener + methodDict['firstParam'] = '' methodDict['jobjects'] = [] methodDict['jenums'] = [] methodDict['jstrings'] = [] @@ -453,14 +480,19 @@ class JavaTranslator(object): if arg is not _method.args[0]: methodDict['params'] += ', ' methodDict['params_impl'] += ', ' + else: + methodDict['firstParam'] = argname + + if (arg.type.isconst): + methodDict['params'] += 'const ' if type(arg.type) is AbsApi.ClassType: - methodDict['params'] += 'Linphone' + arg.type.desc.name.to_camel_case() + ' *' + (argname if arg is not _method.args[0] else 'cptr') + methodDict['params'] += 'Linphone' + arg.type.desc.name.to_camel_case() + ' *' + argname methodDict['jparams'] += 'L' + self.jni_path + arg.type.desc.name.to_camel_case() + ';' methodDict['params_impl'] += 'j_' + argname - methodDict['jobjects'].append({'objectName': argname, 'className': arg.type.desc.name.to_camel_case(),}) + methodDict['jobjects'].append({'objectName': argname, 'className': arg.type.desc.name.to_camel_case(), }) elif type(arg.type) is AbsApi.BaseType: - methodDict['params'] += self.translate_as_c_base_type(arg.type.name) + ' ' + argname + methodDict['params'] += self.translate_as_c_base_type(arg.type) + ' ' + argname methodDict['jparams'] += self.translate_java_jni_base_type_name(arg.type.name) if arg.type.name == 'string': methodDict['params_impl'] += 'j_' + argname @@ -551,7 +583,7 @@ class JniInterface(object): self.callbacks = [] listener = apiClass.listenerInterface for method in listener.methods: - cb = 'linphone_' + listener.name.to_snake_case() + cb = 'linphone_' + listener.name.to_snake_case()[:-9] # Remove _listener at the end cbName = cb + '_' + method.name.to_snake_case() self.callbacks.append({ 'callbackName': cbName, @@ -677,13 +709,14 @@ class GenWrapper(object): project.initFromDir(xmldir) project.check() - self.parser = AbsApi.CParser(project) + self.parser = AbsApi.CParser(project, ['LinphoneBuffer']) self.parser.functionBl = \ ['linphone_vcard_get_belcard',\ 'linphone_core_get_current_vtable',\ 'linphone_factory_get',\ - 'linphone_factory_clean'] - self.parser.classBl += 'LinphoneCoreVTable' + 'linphone_factory_clean',\ + 'linphone_call_zoom_video',\ + 'linphone_config_get_range'] self.parser.parse_all() self.translator = JavaTranslator(package) self.renderer = pystache.Renderer() diff --git a/wrappers/java/jni.mustache b/wrappers/java/jni.mustache index 499e30659..437c2f286 100644 --- a/wrappers/java/jni.mustache +++ b/wrappers/java/jni.mustache @@ -18,15 +18,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -#include "linphone/core_utils.h" #include +#include "belle-sip/object.h" #include "mediastreamer2/mediastream.h" #include "mediastreamer2/mscommon.h" #include "mediastreamer2/msmediaplayer.h" #include "mediastreamer2/msutils.h" #include "mediastreamer2/devices.h" #include "mediastreamer2/msjava.h" +#include "linphone/core_utils.h" #include "linphone/core.h" #include "linphone/tunnel.h" #include "linphone/account_creator.h" @@ -44,12 +45,12 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *ajvm, void *reserved) { #ifdef __ANDROID__ ms_set_jvm(ajvm); #endif /* __ANDROID__ */ - LinphoneJavaBindings *ljb = new LinphoneJavaBindings(ms_get_jni_env()); - linphone_factory_set_user_data(linphone_factory_get(), ljb); jvm = ajvm; return JNI_VERSION_1_2; } +#define belle_sip_java_user_data_key "java_object" + static const char* GetStringUTFChars(JNIEnv* env, jstring string) { const char *cstring = string ? env->GetStringUTFChars(string, NULL) : NULL; return cstring; @@ -108,28 +109,33 @@ public: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// {{#objects}} -jobject get{{className}}(JNIEnv *env, {{classCName}} *ptr) { +jobject get{{className}}(JNIEnv *env, {{classCName}} *cptr) { jobject jobj = 0; - if (ptr != NULL) { - void *up = {{cPrefix}}_get_user_data(ptr); + if (cptr != NULL) { + void *up = belle_sip_object_data_get((belle_sip_object_t *)cptr, belle_sip_java_user_data_key); LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_factory_get_user_data(linphone_factory_get()); + if (!ljb) { + ljb = new LinphoneJavaBindings(env); + linphone_factory_set_user_data(linphone_factory_get(), ljb); + } + jclass {{cPrefix}}_class = ljb->{{cPrefix}}_class; jmethodID {{cPrefix}}_constructor = ljb->{{cPrefix}}_class_constructor; if (up == NULL) { - jobj = env->NewObject({{cPrefix}}_class, {{cPrefix}}_constructor, (jlong)ptr); - {{cPrefix}}_set_user_data(ptr, (void*)env->NewWeakGlobalRef(jobj)); - {{cPrefix}}_ref(ptr); + jobj = env->NewObject({{cPrefix}}_class, {{cPrefix}}_constructor, (jlong)cptr); + belle_sip_object_data_set((belle_sip_object_t *)cptr, belle_sip_java_user_data_key, (void*)env->NewWeakGlobalRef(jobj), NULL); + {{cPrefix}}_ref(cptr); } else { jobj = env->NewLocalRef((jobject)up); if (jobj == NULL) { // Delete weak ref ? env->DeleteWeakGlobalRef((jobject)up); // takes implicit local ref - jobj = env->NewObject({{cPrefix}}_class, {{cPrefix}}_constructor, (jlong)ptr); - {{cPrefix}}_set_user_data(ptr, (void*)env->NewWeakGlobalRef(jobj)); - {{cPrefix}}_ref(ptr); + jobj = env->NewObject({{cPrefix}}_class, {{cPrefix}}_constructor, (jlong)cptr); + belle_sip_object_data_set((belle_sip_object_t *)cptr, belle_sip_java_user_data_key, (void*)env->NewWeakGlobalRef(jobj), NULL); + {{cPrefix}}_ref(cptr); } } } @@ -138,8 +144,8 @@ jobject get{{className}}(JNIEnv *env, {{classCName}} *ptr) { void Java_{{jniPrefix}}{{classImplName}}_unref(JNIEnv* env, jobject thiz, jlong ptr) { {{classCName}} *cptr = ({{classCName}}*)ptr; - jobject wref = (jobject){{cPrefix}}_get_user_data(cptr); - {{cPrefix}}_set_user_data(cptr, NULL); + jobject wref = (jobject)belle_sip_object_data_get((belle_sip_object_t *)cptr, belle_sip_java_user_data_key); + belle_sip_object_data_set((belle_sip_object_t *)cptr, belle_sip_java_user_data_key, NULL, NULL); if (wref) { env->DeleteWeakGlobalRef(wref); } @@ -161,24 +167,23 @@ static inline void handle_possible_java_exception(JNIEnv *env, jobject listener) {{#callbacks}} static {{return}} {{callbackName}}({{params}}) { JNIEnv *env = 0; - jint result = jvm->AttachCurrentThread(&env,NULL); - LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_factory_get_user_data(linphone_factory_get()); - if (result != 0) { + jint jvmResult = jvm->AttachCurrentThread(&env,NULL); + if (jvmResult != 0) { ms_error("cannot attach VM"); - return; + return{{returnIfFail}}; } {{#isSingleListener}} - {{classCName}}Cbs *cbs = {{cPrefix}}_get_callbacks(cptr); + {{classCName}}Cbs *cbs = {{cPrefix}}_get_callbacks({{firstParam}}); {{/isSingleListener}} {{#isMultiListener}} - {{classCName}}Cbs *cbs = {{cPrefix}}_get_current_callbacks(cptr); + {{classCName}}Cbs *cbs = {{cPrefix}}_get_current_callbacks({{firstParam}}); {{/isMultiListener}} jobject jlistener = (jobject) {{cPrefix}}_cbs_get_user_data(cbs); if (jlistener == NULL) { ms_warning("{{name}}() notification without listener"); - return ; + return{{returnIfFail}}; } jclass jlistenerClass = (jclass) env->GetObjectClass(jlistener); @@ -186,9 +191,10 @@ static {{return}} {{callbackName}}({{params}}) { env->DeleteLocalRef(jlistenerClass); {{#jobjects}} - jobject j_{{objectName}} = get{{className}}(env, {{objectName}}); + jobject j_{{objectName}} = get{{className}}(env, (Linphone{{className}} *){{objectName}}); {{/jobjects}} {{#jenums}} + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_factory_get_user_data(linphone_factory_get()); jobject j_{{enumName}} = env->CallStaticObjectMethod(ljb->{{cEnumPrefix}}_class, ljb->{{cEnumPrefix}}_class_constructor_from_int, (jint){{enumName}}); {{/jenums}} {{#jstrings}} @@ -209,6 +215,9 @@ static {{return}} {{callbackName}}({{params}}) { {{/jstrings}} handle_possible_java_exception(env, jlistener); + {{#hasReturn}} + return 0; + {{/hasReturn}} } {{/callbacks}} @@ -243,7 +252,7 @@ void {{jniPackage}}{{classCName}}Impl_removeListener(JNIEnv* env, jobject thiz, {{classCName}} *cptr = ({{classCName}}*)ptr; const bctbx_list_t *cbs_list = {{cPrefix}}_get_callbacks_list(cptr); bctbx_list_t *it; - for (it = cbs_list; it != NULL; it = it->next) { + for (it = (bctbx_list_t *)cbs_list; it != NULL; it = it->next) { {{classCName}}Cbs *cbs = ({{classCName}}Cbs *)it->data; if ({{cPrefix}}_cbs_get_user_data(cbs) == jlistener) { {{cPrefix}}_remove_callbacks(cptr, cbs); @@ -258,16 +267,15 @@ void {{jniPackage}}{{classCName}}Impl_removeListener(JNIEnv* env, jobject thiz, {{#methods}} {{return}} {{name}}({{params}}) { - {{#notStatic}}{{classCName}} *cptr = ({{classCName}}*)ptr;{{/notStatic}} - {{#strings}} + {{#notStatic}}{{classCName}} *cptr = ({{classCName}}*)ptr;{{/notStatic}}{{#strings}} const char* c_{{string}} = GetStringUTFChars(env, {{string}}); {{/strings}}{{#objects}} {{objectClassCName}}* c_{{object}} = NULL; if ({{object}}) c_{{object}} = ({{objectClassCName}}*)GetObjectNativePtr(env, {{object}}); {{/objects}}{{#lists}} bctbx_list_t *bctbx_list_{{list}} = NULL; - int count = env->GetArrayLength({{list}}); - for (int i=0; i < count; i++) { + int {{list}}_count = env->GetArrayLength({{list}}); + for (int i=0; i < {{list}}_count; i++) { {{#isStringList}} jstring obj = (jstring) env->GetObjectArrayElement({{list}}, i); const char *str = GetStringUTFChars(env, obj); @@ -278,30 +286,34 @@ void {{jniPackage}}{{classCName}}Impl_removeListener(JNIEnv* env, jobject thiz, {{/isStringList}} {{#isObjList}} jobject obj = env->GetObjectArrayElement({{list}}, i); - bctbx_list_{{list}} = bctbx_list_append(bctbx_list_{{list}}, GetObjectNativePtr(env, obj)); + bctbx_list_{{list}} = bctbx_list_append(bctbx_list_{{list}}, ({{objectClassCName}} *)GetObjectNativePtr(env, obj)); {{/isObjList}} } {{/lists}}{{#hasListReturn}} - bctbx_list_t *list = {{c_name}}({{#notStatic}}cptr{{/notStatic}}{{params_impl}}); + const bctbx_list_t *list = {{c_name}}({{#notStatic}}cptr{{/notStatic}}{{params_impl}}); size_t count = bctbx_list_size(list); {{#isRealObjectArray}} LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_factory_get_user_data(linphone_factory_get()); - jobjectArray jni_list_result = env->NewObjectArray(count, ljb->{{objectCPrefix}}_class, NULL);{{/isRealObjectArray}} - {{#isStringObjectArray}}jobjectArray jni_list_result = env->NewObjectArray(count, env->FindClass("java/lang/String"), env->NewStringUTF(""));{{/isStringObjectArray}} + jobjectArray jni_list_result = env->NewObjectArray((int)count, ljb->{{objectCPrefix}}_class, NULL);{{/isRealObjectArray}} + {{#isStringObjectArray}}jobjectArray jni_list_result = env->NewObjectArray((int)count, env->FindClass("java/lang/String"), env->NewStringUTF(""));{{/isStringObjectArray}} for (size_t i = 0; i < count; i++) { {{#isRealObjectArray}} {{objectClassCName}}* c_object = ({{objectClassCName}}*)list->data; - jobject object = get{{objectClassName}}(c_object); + jobject object = get{{objectClassName}}(env, c_object); {{/isRealObjectArray}} - {{#isStringObjectArray}}jstring object = list->data ? env->NewStringUTF(list->data) : 0;{{/isStringObjectArray}} + {{#isStringObjectArray}}const char *cstring = (const char *)list->data; + jstring object = cstring ? env->NewStringUTF(cstring) : 0;{{/isStringObjectArray}} if (object != 0) { - env->SetObjectArrayElement(jni_list_result, i, object); + env->SetObjectArrayElement(jni_list_result, (int)i, object); {{#isRealObjectArray}}env->DeleteLocalRef(object);{{/isRealObjectArray}} } list = bctbx_list_next(list); } - {{/hasListReturn}}{{#hasNormalReturn}} - {{#hasReturn}}{{return}} jni_result = {{#returnObject}}get{{returnClassName}}({{/returnObject}}{{/hasReturn}}{{c_name}}({{#notStatic}}cptr{{/notStatic}}{{params_impl}}){{#returnObject}}){{/returnObject}}; + {{/hasListReturn}}{{#hasStringReturn}} + const char *c_string = {{c_name}}({{#notStatic}}cptr{{/notStatic}}{{params_impl}}){{#returnObject}}){{/returnObject}}; + jstring jni_result = (c_string != NULL) ? env->NewStringUTF(c_string) : NULL; + {{/hasStringReturn}}{{#hasNormalReturn}} + {{#hasReturn}}{{return}} jni_result = ({{return}}){{#returnObject}}get{{returnClassName}}(env, (Linphone{{returnClassName}} *){{/returnObject}}{{/hasReturn}}{{c_name}}({{#notStatic}}cptr{{/notStatic}}{{params_impl}}){{#returnObject}}){{/returnObject}}; {{/hasNormalReturn}}{{#strings}} ReleaseStringUTFChars(env, {{string}}, c_{{string}}); {{/strings}}{{#hasReturn}}return jni_result;{{/hasReturn}}{{#hasListReturn}}return jni_list_result;{{/hasListReturn}}