mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
#15414: Generate SWIG JNI interface for basic functions
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@ -75,3 +75,7 @@ ID
|
||||
|
||||
# IDE stuffs
|
||||
nbproject
|
||||
|
||||
# JNI generated files
|
||||
*_wrap.cpp
|
||||
*_loader.c
|
||||
|
@ -21,6 +21,7 @@ MY_DBUS=libdbus-c++-0.9.0-android
|
||||
MY_SPEEX=speex
|
||||
MY_OPENSSL=openssl
|
||||
MY_LIBYAML=libyaml
|
||||
MY_JNI_WRAP=callmanager_wrap.cpp
|
||||
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
@ -67,6 +68,7 @@ LOCAL_SRC_FILES := \
|
||||
config/yamlnode.cpp \
|
||||
dbus/callmanager.cpp \
|
||||
dbus/configurationmanager.cpp \
|
||||
dbus/$(MY_JNI_WRAP) \
|
||||
dbus/instance.cpp \
|
||||
dbus/dbusmanager.cpp \
|
||||
history/historyitem.cpp \
|
||||
|
85
daemon/src/JavaJNI2CJNI_Load.py
Executable file
85
daemon/src/JavaJNI2CJNI_Load.py
Executable file
@ -0,0 +1,85 @@
|
||||
#!/usr/bin/python
|
||||
import getopt, sys
|
||||
import re
|
||||
from string import Template
|
||||
|
||||
def type_to_signature(itype):
|
||||
if len(itype) > 2:
|
||||
if itype[-2:] == '[]':
|
||||
return "[%s" % type_to_signature(itype[:-2])
|
||||
if itype == "int":
|
||||
return "I"
|
||||
if itype == "long":
|
||||
return "J"
|
||||
if itype == "void":
|
||||
return "V"
|
||||
if itype == "boolean":
|
||||
return "Z"
|
||||
if itype == "byte":
|
||||
return "B"
|
||||
if itype == "char":
|
||||
return "C"
|
||||
if itype == "short":
|
||||
return "S"
|
||||
if itype == "float":
|
||||
return "F"
|
||||
if itype == "double":
|
||||
return "D"
|
||||
if itype == "String":
|
||||
return "Ljava/lang/String;"
|
||||
if itype == "Object":
|
||||
return "Ljava/lang/Object;"
|
||||
return "Lcom/savoirfairelinux/sflphone/client/%s;" % itype
|
||||
|
||||
def parse_java_file(input_stream, package, module):
|
||||
outputs = []
|
||||
package_prefix = "Java_%s_%sJNI" % (package.replace(".", "_"), module)
|
||||
for line in input_stream:
|
||||
definition = re.match(r'.*public final static native ([^\( ]*) ([^\)]*)\(([^)]*)\).*',line)
|
||||
if definition is not None:
|
||||
retour = definition.group(1)
|
||||
name = definition.group(2)
|
||||
args = definition.group(3)
|
||||
args_sigs = []
|
||||
args_frags = args.split(',')
|
||||
for args_frag in args_frags:
|
||||
argf = re.match(r'(\b)?([^ ]+) .*', args_frag.strip())
|
||||
if argf is not None:
|
||||
args_sigs.append(type_to_signature(argf.group(2)))
|
||||
sig = "(%s)%s" % (''.join(args_sigs), type_to_signature(retour))
|
||||
outputs.append("{\"%s\", \"%s\", (void*)& %s_%s}" % (name, sig, package_prefix, name.replace('_', '_1')))
|
||||
return outputs
|
||||
|
||||
def render_to_template(defs, template_string):
|
||||
template = Template(template_string)
|
||||
return template.substitute(defs= ",\r\n".join(defs) )
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "i:o:t:m:p:", ["input=", "output=", "template=", "module=", "package="])
|
||||
except getopt.GetoptError, err:
|
||||
# print help information and exit:
|
||||
print str(err) # will print something like "option -a not recognized"
|
||||
sys.exit(2)
|
||||
input_stream = None
|
||||
output_file = None
|
||||
template_string = None
|
||||
package = ""
|
||||
module = ""
|
||||
for o, a in opts:
|
||||
if o in ("-i", "--input"):
|
||||
input_stream = open(a)
|
||||
if o in ("-o", "--output"):
|
||||
output_file = open(a, "w")
|
||||
if o in ("-t", "--template"):
|
||||
template_string = open(a).read()
|
||||
if o in ("-m", "--module"):
|
||||
module = a
|
||||
if o in ("-p", "--package"):
|
||||
package = a
|
||||
|
||||
defs = parse_java_file(input_stream, package, module)
|
||||
output_file.write(render_to_template(defs, template_string))
|
||||
output_file.close()
|
||||
input_stream.close()
|
83
daemon/src/dbus/callmanager.i
Normal file
83
daemon/src/dbus/callmanager.i
Normal file
@ -0,0 +1,83 @@
|
||||
|
||||
/* File : callmanager.i */
|
||||
%module sflphoneservice
|
||||
|
||||
%include "typemaps.i"
|
||||
%include "std_string.i" /* std::string typemaps */
|
||||
%include "enums.swg"
|
||||
%include "arrays_java.i";
|
||||
%include "carrays.i";
|
||||
|
||||
/* void* shall be handled as byte arrays */
|
||||
%typemap(jni) void * "void *"
|
||||
%typemap(jtype) void * "byte[]"
|
||||
%typemap(jstype) void * "byte[]"
|
||||
%typemap(javain) void * "$javainput"
|
||||
%typemap(in) void * %{
|
||||
$1 = $input;
|
||||
%}
|
||||
%typemap(javadirectorin) void * "$jniinput"
|
||||
%typemap(out) void * %{
|
||||
$result = $1;
|
||||
%}
|
||||
%typemap(javaout) void * {
|
||||
return $jnicall;
|
||||
}
|
||||
|
||||
/* not parsed by SWIG but needed by generated C files */
|
||||
%{
|
||||
#include <managerimpl.h>
|
||||
#include <dbus/callmanager.h>
|
||||
|
||||
namespace Manager {
|
||||
extern ManagerImpl& instance();
|
||||
}
|
||||
%}
|
||||
|
||||
/* parsed by SWIG to generate all the glue */
|
||||
/* %include "../managerimpl.h" */
|
||||
/* %include <dbus/callmanager.h> */
|
||||
|
||||
/* %nodefaultctor ManagerImpl;
|
||||
%nodefaultdtor ManagerImpl; */
|
||||
|
||||
class ManagerImpl {
|
||||
public:
|
||||
void init(const std::string &config_file);
|
||||
void setPath(const std::string &path);
|
||||
bool outgoingCall(const std::string&, const std::string&, const std::string&, const std::string& = "");
|
||||
void refuseCall(const std::string& id);
|
||||
bool answerCall(const std::string& id);
|
||||
void hangupCall(const std::string& id);
|
||||
};
|
||||
|
||||
//%rename(Manager_instance) Manager::instance;
|
||||
|
||||
namespace Manager {
|
||||
|
||||
ManagerImpl& Manager::instance()
|
||||
{
|
||||
// Meyers singleton
|
||||
static ManagerImpl instance_;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//class CallManager {
|
||||
//public:
|
||||
// /* Manager::instance().outgoingCall */
|
||||
// void placeCall(const std::string& accountID,
|
||||
// const std::string& callID,
|
||||
// const std::string& to);
|
||||
// /* Manager::instance().refuseCall */
|
||||
// void refuse(const std::string& callID);
|
||||
// /* Manager::instance().answerCall */
|
||||
// void accept(const std::string& callID);
|
||||
// /* Manager::instance().hangupCall */
|
||||
// void hangUp(const std::string& callID);
|
||||
//};
|
||||
|
||||
#ifndef SWIG
|
||||
/* some bad declarations */
|
||||
#endif
|
@ -91,7 +91,9 @@
|
||||
#include <sstream>
|
||||
#include <sys/types.h> // mkdir(2)
|
||||
#include <sys/stat.h> // mkdir(2)
|
||||
#include <jni.h>
|
||||
|
||||
extern JavaVM *gJavaVM;
|
||||
static jobject gManagerObject, gDataObject;
|
||||
|
||||
ManagerImpl::ManagerImpl() :
|
||||
@ -314,6 +316,7 @@ void ManagerImpl::init(const std::string &config_file)
|
||||
|
||||
//history_.load(preferences.getHistoryLimit());
|
||||
registerAccounts();
|
||||
INFO("init ended");
|
||||
}
|
||||
|
||||
void ManagerImpl::setPath(const std::string &path) {
|
||||
|
104
daemon/src/sflphoneservice.c.template
Normal file
104
daemon/src/sflphoneservice.c.template
Normal file
@ -0,0 +1,104 @@
|
||||
#include "logger.h"
|
||||
|
||||
JavaVM *gJavaVM;
|
||||
const char *ksflphoneservicePath = "com/savoirfairelinux/sflphone/client/sflphoneserviceJNI";
|
||||
//const char *kManagerPath = "com/savoirfairelinux/sflphone/client/ManagerImpl";
|
||||
//static jobject gManagerObject, gDataObject;
|
||||
|
||||
//void initClassHelper(JNIEnv *env, const char *path, jobject *objptr) {
|
||||
// jclass cls;
|
||||
//
|
||||
// INFO("initClassHelper");
|
||||
//
|
||||
// cls= env->FindClass(path);
|
||||
// if(!cls) {
|
||||
// ERROR("initClassHelper: failed to get %s class reference", path);
|
||||
// return;
|
||||
// }
|
||||
// jmethodID constr = env->GetMethodID(cls, "<init>", "()V");
|
||||
// INFO("initClassHelper: %s method found", path);
|
||||
//
|
||||
// if(!constr) {
|
||||
// ERROR("initClassHelper: failed to get %s constructor", path);
|
||||
// return;
|
||||
// }
|
||||
// jobject obj = env->NewObject(cls, constr);
|
||||
// INFO("initClassHelper: %s constructor found", path);
|
||||
//
|
||||
// if(!obj) {
|
||||
// ERROR("initClassHelper: failed to create a %s object", path);
|
||||
// return;
|
||||
// }
|
||||
// /* protect cached object instances from Android GC */
|
||||
// (*objptr) = env->NewGlobalRef(obj);
|
||||
// INFO("initClassHelper: object found %x", objptr);
|
||||
//}
|
||||
|
||||
void deinitClassHelper(JNIEnv *env, jobject obj) {
|
||||
INFO("deinitClassHelper");
|
||||
|
||||
/* delete cached object instances */
|
||||
env->DeleteGlobalRef(obj);
|
||||
INFO("deinitClassHelper: object %x deleted", obj);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||
JNIEnv *env;
|
||||
jclass clazz;
|
||||
jint r;
|
||||
|
||||
INFO("JNI_OnLoad");
|
||||
|
||||
//Assume it is c++
|
||||
r = vm->GetEnv ((void **) &env, JNI_VERSION_1_6);
|
||||
if (r != JNI_OK) {
|
||||
ERROR("JNI_OnLoad: failed to get the environment using GetEnv()");
|
||||
return -1;
|
||||
}
|
||||
INFO("JNI_Onload: GetEnv %p", env);
|
||||
|
||||
clazz = env->FindClass (ksflphoneservicePath);
|
||||
if (!clazz) {
|
||||
ERROR("JNI_Onload: whoops, %s class not found!", ksflphoneservicePath);
|
||||
}
|
||||
gJavaVM = vm;
|
||||
INFO("JNI_Onload: JavaVM %p", gJavaVM);
|
||||
|
||||
/* put instances of class object we need into cache */
|
||||
//initClassHelper(env, kManagerPath, &gManagerObject);
|
||||
|
||||
JNINativeMethod methods[] = {
|
||||
|
||||
$defs
|
||||
|
||||
};
|
||||
|
||||
r = env->RegisterNatives (clazz, methods, (int) (sizeof(methods) / sizeof(methods[0])));
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
void JNI_OnUnLoad(JavaVM* vm, void* reserved) {
|
||||
JNIEnv* env;
|
||||
jclass clazz;
|
||||
|
||||
INFO("JNI_OnUnLoad");
|
||||
|
||||
/* get env */
|
||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
||||
ERROR("JNI_OnUnLoad: failed to get the environment using GetEnv()");
|
||||
return;
|
||||
}
|
||||
INFO("JNI_OnUnLoad: GetEnv %p", env);
|
||||
|
||||
/* Get jclass with env->FindClass */
|
||||
clazz = env->FindClass(ksflphoneservicePath);
|
||||
if (!clazz) {
|
||||
ERROR("JNI_OnUnLoad: whoops, %s class not found!", ksflphoneservicePath);
|
||||
}
|
||||
|
||||
/* remove instances of class object we need into cache */
|
||||
//deinitClassHelper(env, gManagerObject);
|
||||
|
||||
env->UnregisterNatives(clazz);
|
||||
INFO("JNI_OnUnLoad: Native functions unregistered");
|
||||
}
|
Reference in New Issue
Block a user