From 2f415bc619c758155b77aef31f0d3392717c7496 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 18 Nov 2013 22:23:41 +0100 Subject: [PATCH] modify JNI to allow passing raw data in LinphoneContent. --- coreapi/linphonecore_jni.cc | 67 ++++++++++++------- .../org/linphone/core/LinphoneContent.java | 16 +++++ .../linphone/core/LinphoneCoreFactory.java | 7 +- .../linphone/core/LinphoneContentImpl.java | 31 +++++++-- .../core/LinphoneCoreFactoryImpl.java | 8 ++- .../org/linphone/core/LinphoneCoreImpl.java | 10 +-- .../org/linphone/core/LinphoneEventImpl.java | 12 ++-- 7 files changed, 110 insertions(+), 41 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index a0e212c26..fa583f144 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -3102,7 +3102,7 @@ extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getUpnpExternalIpaddr * Signature: (JJLjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; */ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_subscribe(JNIEnv *env, jobject jcore, jlong coreptr, jlong addrptr, - jstring jevname, jint expires, jstring jtype, jstring jsubtype, jstring jdata){ + jstring jevname, jint expires, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){ LinphoneCore *lc=(LinphoneCore*)coreptr; LinphoneAddress *addr=(LinphoneAddress*)addrptr; LinphoneContent content={0}; @@ -3114,14 +3114,16 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_subscribe(JNIE if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); - content.data=(void*)env->GetStringUTFChars(jdata,NULL); - content.size=strlen((char*)content.data); + content.encoding=jencoding ? (char*)env->GetStringUTFChars(jsubtype,NULL) : NULL; + content.data=(void*)env->GetByteArrayElements(jdata,NULL); + content.size=env->GetArrayLength(jdata); } ev=linphone_core_subscribe(lc,addr,evname,expires,content.type ? &content : NULL); if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); - env->ReleaseStringUTFChars(jdata,(char*)content.data); + if (jencoding) env->ReleaseStringUTFChars(jencoding,content.encoding); + env->ReleaseByteArrayElements(jdata,(jbyte*)content.data,JNI_ABORT); } env->ReleaseStringUTFChars(jevname,evname); if (ev){ @@ -3136,7 +3138,7 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_subscribe(JNIE * Signature: (JJLjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; */ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_publish(JNIEnv *env, jobject jobj, jlong coreptr, jlong addrptr, jstring jevname, jint expires, - jstring jtype, jstring jsubtype, jstring jdata){ + jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){ LinphoneCore *lc=(LinphoneCore*)coreptr; LinphoneAddress *addr=(LinphoneAddress*)addrptr; LinphoneContent content={0}; @@ -3148,14 +3150,16 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_publish(JNIEnv if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); - content.data=(void*)env->GetStringUTFChars(jdata,NULL); - content.size=strlen((char*)content.data); + content.encoding=jencoding ? (char*)env->GetStringUTFChars(jsubtype,NULL) : NULL; + content.data=(void*)env->GetByteArrayElements(jdata,NULL); + content.size=env->GetArrayLength(jdata); } ev=linphone_core_publish(lc,addr,evname,expires,content.type ? &content : NULL); if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); - env->ReleaseStringUTFChars(jdata,(char*)content.data); + if (jencoding) env->ReleaseStringUTFChars(jencoding,content.encoding); + env->ReleaseByteArrayElements(jdata,(jbyte*)content.data,JNI_ABORT); } env->ReleaseStringUTFChars(jevname,evname); if (ev){ @@ -3295,15 +3299,22 @@ extern "C" jintArray Java_org_linphone_core_LpConfigImpl_getIntRange(JNIEnv *env static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *content){ jclass contentClass; jmethodID ctor; - jstring jtype, jsubtype, jdata; + jstring jtype, jsubtype, jencoding; + jbyteArray jdata=NULL; contentClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneContentImpl")); - ctor = env->GetMethodID(contentClass,"", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); + ctor = env->GetMethodID(contentClass,"", "(Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;)V"); jtype=env->NewStringUTF(content->type); jsubtype=env->NewStringUTF(content->subtype); - jdata=content->data ? env->NewStringUTF((const char*)content->data) : NULL; - jobject jobj=env->NewObject(contentClass,ctor,jtype, jsubtype, jdata); + jencoding=content->encoding ? env->NewStringUTF(content->encoding) : NULL; + + if (content->data){ + jdata=env->NewByteArray(content->size); + env->SetByteArrayRegion(jdata,0,content->size,(jbyte*)content->data); + } + + jobject jobj=env->NewObject(contentClass,ctor,jtype, jsubtype, jdata,jencoding); env->DeleteGlobalRef(contentClass); return jobj; } @@ -3327,7 +3338,7 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_getCont * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_setContent(JNIEnv *env, jobject jobj, jlong infoptr, jstring jtype, jstring jsubtype, jstring jdata){ - LinphoneContent content; + LinphoneContent content={0}; content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); @@ -3428,7 +3439,7 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_denySubscription * Method: notify * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I */ -JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jstring jdata){ +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){ LinphoneContent content={0}; LinphoneEvent *ev=(LinphoneEvent*)evptr; jint err; @@ -3436,8 +3447,9 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *e if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); - content.data=(void*)env->GetStringUTFChars(jdata,NULL); - content.size=strlen((char*)content.data); + content.encoding=jencoding ? (char*)env->GetStringUTFChars(jsubtype,NULL) : NULL; + content.data=(void*)env->GetByteArrayElements(jdata,NULL); + content.size=env->GetArrayLength(jdata); } err=linphone_event_notify(ev,content.type ? &content : NULL); @@ -3445,7 +3457,8 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *e if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); - env->ReleaseStringUTFChars(jdata,(char*)content.data); + if (jencoding) env->ReleaseStringUTFChars(jencoding,content.encoding); + env->ReleaseByteArrayElements(jdata,(jbyte*)content.data,JNI_ABORT); } return err; } @@ -3455,7 +3468,7 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *e * Method: updateSubscribe * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I */ -JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jstring jdata){ +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){ LinphoneContent content={0}; LinphoneEvent *ev=(LinphoneEvent*)evptr; jint err; @@ -3463,8 +3476,9 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe( if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); - content.data=(void*)env->GetStringUTFChars(jdata,NULL); - content.size=strlen((char*)content.data); + content.encoding=jencoding ? (char*)env->GetStringUTFChars(jsubtype,NULL) : NULL; + content.data=(void*)env->GetByteArrayElements(jdata,NULL); + content.size=env->GetArrayLength(jdata); } err=linphone_event_update_subscribe(ev,content.type ? &content : NULL); @@ -3472,7 +3486,8 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe( if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); - env->ReleaseStringUTFChars(jdata,(char*)content.data); + if (jencoding) env->ReleaseStringUTFChars(jencoding,content.encoding); + env->ReleaseByteArrayElements(jdata,(jbyte*)content.data,JNI_ABORT); } return err; } @@ -3482,7 +3497,7 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe( * Method: updatePublish * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I */ -JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updatePublish(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jstring jdata){ +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updatePublish(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){ LinphoneContent content={0}; LinphoneEvent *ev=(LinphoneEvent*)evptr; jint err; @@ -3490,8 +3505,9 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updatePublish(JN if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); - content.data=(void*)env->GetStringUTFChars(jdata,NULL); - content.size=strlen((char*)content.data); + content.encoding=jencoding ? (char*)env->GetStringUTFChars(jsubtype,NULL) : NULL; + content.data=(void*)env->GetByteArrayElements(jdata,NULL); + content.size=env->GetArrayLength(jdata); } err=linphone_event_update_publish(ev,content.type ? &content : NULL); @@ -3499,7 +3515,8 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updatePublish(JN if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); - env->ReleaseStringUTFChars(jdata,(char*)content.data); + if (jencoding) env->ReleaseStringUTFChars(jencoding,content.encoding); + env->ReleaseByteArrayElements(jdata,(jbyte*)content.data,JNI_ABORT); } return err; } diff --git a/java/common/org/linphone/core/LinphoneContent.java b/java/common/org/linphone/core/LinphoneContent.java index b3811006f..10c6e3dc9 100644 --- a/java/common/org/linphone/core/LinphoneContent.java +++ b/java/common/org/linphone/core/LinphoneContent.java @@ -17,11 +17,19 @@ public interface LinphoneContent { * @return the subtype */ String getSubtype(); + /** + * Get the encoding applied to the data, can be null if no encoding. + **/ + String getEncoding(); /** * Get the data as a string. * @return the data */ String getDataAsString(); + /** + * Get the data as a byte array. + **/ + byte [] getData(); /** * Get the data size. * @return the data size. @@ -38,9 +46,17 @@ public interface LinphoneContent { * @param subtype the subtype */ void setSubtype(String subtype); + /** + * Set the encoding applied to the data, can be null if no encoding. + **/ + void setEncoding(String encoding); /** * Set the data, supplied as String. * @param data the data */ void setStringData(String data); + /** + * Set the data, as a byte buffer. + **/ + void setData(byte data[]); } diff --git a/java/common/org/linphone/core/LinphoneCoreFactory.java b/java/common/org/linphone/core/LinphoneCoreFactory.java index dfbeb883b..95cfdeaf0 100644 --- a/java/common/org/linphone/core/LinphoneCoreFactory.java +++ b/java/common/org/linphone/core/LinphoneCoreFactory.java @@ -108,10 +108,15 @@ abstract public class LinphoneCoreFactory { abstract public LinphoneFriend createLinphoneFriend(); /** - * Create a LinphoneContent object + * Create a LinphoneContent object from string data. */ abstract public LinphoneContent createLinphoneContent(String type, String subType, String data); + /** + * Create a LinphoneContent object from byte array. + */ + abstract public LinphoneContent createLinphoneContent(String type, String subType,byte [] data, String encoding); + /** * Create a PresenceActivity object. */ diff --git a/java/impl/org/linphone/core/LinphoneContentImpl.java b/java/impl/org/linphone/core/LinphoneContentImpl.java index f74711042..b12e6580f 100644 --- a/java/impl/org/linphone/core/LinphoneContentImpl.java +++ b/java/impl/org/linphone/core/LinphoneContentImpl.java @@ -1,11 +1,14 @@ package org.linphone.core; public class LinphoneContentImpl implements LinphoneContent { - private String mType, mSubtype, mData; - public LinphoneContentImpl(String type, String subtype, String data){ + private String mType, mSubtype, mEncoding; + private byte[] mData; + + public LinphoneContentImpl(String type, String subtype, byte data[], String encoding ){ mType=type; mSubtype=subtype; mData=data; + mEncoding=encoding; } @Override @@ -20,12 +23,12 @@ public class LinphoneContentImpl implements LinphoneContent { @Override public String getDataAsString() { - return mData; + return new String(mData); } @Override public int getSize() { - return mData.length(); + return mData.length; } @Override @@ -40,7 +43,27 @@ public class LinphoneContentImpl implements LinphoneContent { @Override public void setStringData(String data) { + mData=data.getBytes(); + } + + @Override + public void setData(byte data[]){ mData=data; } + @Override + public String getEncoding() { + return mEncoding; + } + + @Override + public byte[] getData() { + return mData; + } + + @Override + public void setEncoding(String encoding) { + mEncoding=encoding; + } + } diff --git a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java index d2f635d4d..e526b47b5 100644 --- a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java @@ -151,10 +151,16 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory { return new LinphoneAuthInfoImpl(username, userid, passwd, ha1, realm, domain); } + @Override + public LinphoneContent createLinphoneContent(String type, String subType, + byte [] data, String encoding) { + return new LinphoneContentImpl(type,subType,data,encoding); + } + @Override public LinphoneContent createLinphoneContent(String type, String subType, String data) { - return new LinphoneContentImpl(type,subType,data); + return new LinphoneContentImpl(type,subType,data.getBytes(),null); } @Override diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index f5740ff41..420547e57 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -1028,19 +1028,21 @@ class LinphoneCoreImpl implements LinphoneCore { return new LinphoneInfoMessageImpl(createInfoMessage(nativePtr)); } - private native Object subscribe(long coreptr, long addrptr, String eventname, int expires, String type, String subtype, String data); + private native Object subscribe(long coreptr, long addrptr, String eventname, int expires, String type, String subtype, byte data [], String encoding); @Override public LinphoneEvent subscribe(LinphoneAddress resource, String eventname, int expires, LinphoneContent content) { return (LinphoneEvent)subscribe(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, eventname, expires, - content!=null ? content.getType() : null, content!=null ? content.getSubtype() : null, content!=null ? content.getDataAsString() : null); + content!=null ? content.getType() : null, content!=null ? content.getSubtype() : null, content!=null ? content.getData() : null, + content!=null ? content.getEncoding() : null); } - private native Object publish(long coreptr, long addrptr, String eventname, int expires, String type, String subtype, String data); + private native Object publish(long coreptr, long addrptr, String eventname, int expires, String type, String subtype, byte data [], String encoding); @Override public LinphoneEvent publish(LinphoneAddress resource, String eventname, int expires, LinphoneContent content) { return (LinphoneEvent)publish(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, eventname, expires, - content!=null ? content.getType() : null, content!=null ? content.getSubtype() : null, content!=null ? content.getDataAsString() : null); + content!=null ? content.getType() : null, content!=null ? content.getSubtype() : null, content!=null ? content.getData() : null, + content!=null ? content.getEncoding() : null); } public void setChatDatabasePath(String path) { diff --git a/java/impl/org/linphone/core/LinphoneEventImpl.java b/java/impl/org/linphone/core/LinphoneEventImpl.java index ab201af99..9890f7cdf 100644 --- a/java/impl/org/linphone/core/LinphoneEventImpl.java +++ b/java/impl/org/linphone/core/LinphoneEventImpl.java @@ -26,22 +26,22 @@ public class LinphoneEventImpl implements LinphoneEvent { denySubscription(mNativePtr,reason.mValue); } - private native int notify(long nativeptr, String type, String subtype, String data); + private native int notify(long nativeptr, String type, String subtype, byte data[], String encoding); @Override public void notify(LinphoneContent content) { - notify(mNativePtr,content.getType(),content.getSubtype(),content.getDataAsString()); + notify(mNativePtr,content.getType(),content.getSubtype(),content.getData(),content.getEncoding()); } - private native int updateSubscribe(long nativePtr, String type, String subtype, String data); + private native int updateSubscribe(long nativePtr, String type, String subtype, byte data[], String encoding); @Override public void updateSubscribe(LinphoneContent content) { - updateSubscribe(mNativePtr,content.getType(), content.getSubtype(),content.getDataAsString()); + updateSubscribe(mNativePtr,content.getType(), content.getSubtype(),content.getData(),content.getEncoding()); } - private native int updatePublish(long nativePtr, String type, String subtype, String data); + private native int updatePublish(long nativePtr, String type, String subtype, byte data[], String encoding); @Override public void updatePublish(LinphoneContent content) { - updatePublish(mNativePtr,content.getType(), content.getSubtype(),content.getDataAsString()); + updatePublish(mNativePtr,content.getType(), content.getSubtype(),content.getData(),content.getEncoding()); } private native int terminate(long nativePtr);