Commit 6f8f4ce5 authored by Emeric Vigier's avatar Emeric Vigier

#15414: Generate SWIG JNI interface for basic functions

parent 0bbf6b9c
......@@ -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 \
......
#!/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()
/* 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) {
......
#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");
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment