Commit 8f039130 authored by Sylvain Berfini's avatar Sylvain Berfini 🐮
Browse files

Added JNI binding for new file transfer and chat message callbacks API

parent c5e96802
......@@ -84,6 +84,7 @@ static jmethodID loghandler_id;
static jobject handler_obj=NULL;
static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *content);
static jobject create_java_linphone_buffer(JNIEnv *env, const LinphoneBuffer *buffer);
#ifdef ANDROID
void linphone_android_log_handler(int prio, char *str) {
......@@ -3063,6 +3064,8 @@ extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createFileTransferM
return (jlong) message;
}
extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_cancelFileTransfer(JNIEnv* env, jobject thiz, jlong ptr) {
linphone_chat_message_cancel_file_transfer((LinphoneChatMessage *)ptr);
}
......@@ -3210,6 +3213,105 @@ extern "C" jint Java_org_linphone_core_LinphoneChatMessageImpl_getStorageId(JNIE
return (jint) linphone_chat_message_get_storage_id((LinphoneChatMessage*)ptr);
}
extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setFileTransferFilepath(JNIEnv* env
,jobject thiz
,jlong ptr, jstring jpath) {
const char* path = env->GetStringUTFChars(jpath, NULL);
linphone_chat_message_set_file_transfer_filepath((LinphoneChatMessage*)ptr, path);
env->ReleaseStringUTFChars(jpath, path);
}
extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_downloadFile(JNIEnv* env
,jobject thiz
,jlong ptr) {
linphone_chat_message_download_file((LinphoneChatMessage*)ptr);
}
static void message_state_changed(LinphoneChatMessage* msg, LinphoneChatMessageState state) {
JNIEnv *env = 0;
jint result = jvm->AttachCurrentThread(&env,NULL);
if (result != 0) {
ms_error("cannot attach VM\n");
return;
}
jobject listener = (jobject) msg->cb_ud;
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageStateChanged","(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneChatMessage$State;)V");
jobject jmessage = getChatMessage(env, msg);
jclass chatMessageStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessage$State"));
jmethodID chatMessageStateFromIntId = env->GetStaticMethodID(chatMessageStateClass, "fromInt","(I)Lorg/linphone/core/LinphoneChatMessage$State;");
env->CallVoidMethod(listener, method, jmessage, env->CallStaticObjectMethod(chatMessageStateClass, chatMessageStateFromIntId, (jint)state));
if (state == LinphoneChatMessageStateDelivered || state == LinphoneChatMessageStateNotDelivered) {
env->DeleteGlobalRef(listener);
}
}
static void file_transfer_progress_indication(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total) {
JNIEnv *env = 0;
jint result = jvm->AttachCurrentThread(&env,NULL);
if (result != 0) {
ms_error("cannot attach VM\n");
return;
}
jobject listener = (jobject) msg->cb_ud;
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferProgressChanged", "(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;II)V");
jobject jmessage = getChatMessage(env, msg);
env->CallVoidMethod(listener, method, jmessage, content ? create_java_linphone_content(env, content) : NULL, offset, total);
}
static void file_transfer_recv(LinphoneChatMessage *msg, const LinphoneContent* content, const LinphoneBuffer *buffer) {
JNIEnv *env = 0;
jint result = jvm->AttachCurrentThread(&env,NULL);
if (result != 0) {
ms_error("cannot attach VM\n");
return;
}
jobject listener = (jobject) msg->cb_ud;
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferReceived", "(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;Lorg/linphone/core/LinphoneBuffer;)V");
jobject jmessage = getChatMessage(env, msg);
env->CallVoidMethod(listener, method, jmessage, content ? create_java_linphone_content(env, content) : NULL, buffer ? create_java_linphone_buffer(env, buffer) : NULL);
}
static LinphoneBuffer* file_transfer_send(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t size) {
JNIEnv *env = 0;
jint result = jvm->AttachCurrentThread(&env,NULL);
if (result != 0) {
ms_error("cannot attach VM\n");
return NULL;
}
jobject listener = (jobject) msg->cb_ud;
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferSent","(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;IILorg/linphone/core/LinphoneBuffer;)V");
jobject jmessage = getChatMessage(env, msg);
jobject jbuffer = create_java_linphone_buffer(env, NULL);
env->CallVoidMethod(listener, method, jmessage, content ? create_java_linphone_content(env, content) : NULL, offset, size, jbuffer);
//TODO
LinphoneBuffer *buffer = linphone_buffer_new();
return buffer;
}
extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) {
jobject listener = env->NewGlobalRef(jlistener);
LinphoneChatMessage *message = (LinphoneChatMessage *)ptr;
LinphoneChatMessageCbs *cbs;
message->cb_ud = listener;
cbs = linphone_chat_message_get_callbacks(message);
linphone_chat_message_cbs_set_msg_state_changed(cbs, message_state_changed);
linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_recv);
linphone_chat_message_cbs_set_file_transfer_send(cbs, file_transfer_send);
}
extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_unref(JNIEnv* env
,jobject thiz
,jlong ptr) {
......@@ -3292,11 +3394,15 @@ extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage2(JNIEnv*
linphone_chat_room_send_message2((LinphoneChatRoom*)chatroom_ptr, (LinphoneChatMessage*)messagePtr, chat_room_impl_callback, (void*)listener);
}
extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_startFileDownload(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) {
jobject listener = env->NewGlobalRef(jlistener);
LinphoneChatMessage * message = (LinphoneChatMessage *)ptr;
message->cb_ud = listener;
linphone_chat_message_start_file_download(message, chat_room_impl_callback, NULL);
extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendChatMessage(JNIEnv* env
,jobject thiz
,jlong chatroom_ptr
,jobject message
,jlong messagePtr) {
message = env->NewGlobalRef(message);
linphone_chat_message_ref((LinphoneChatMessage*)messagePtr);
linphone_chat_message_set_user_data((LinphoneChatMessage*)messagePtr, message);
linphone_chat_room_send_chat_message((LinphoneChatRoom*)chatroom_ptr, (LinphoneChatMessage*)messagePtr);
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(JNIEnv* env
......@@ -4445,6 +4551,27 @@ static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *
return jobj;
}
static jobject create_java_linphone_buffer(JNIEnv *env, const LinphoneBuffer *buffer){
jclass bufferClass;
jmethodID ctor;
jstring jtype, jsubtype, jencoding, jname;
jbyteArray jdata = NULL;
jint jsize = 0;
bufferClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneBufferImpl"));
ctor = env->GetMethodID(bufferClass,"<init>", "([BI)V");
jsize = buffer ? (jint) buffer->size : 0;
if (buffer && buffer->content) {
jdata = env->NewByteArray(buffer->size);
env->SetByteArrayRegion(jdata, 0, buffer->size, (jbyte*)buffer->content);
}
jobject jobj = env->NewObject(bufferClass, ctor, jdata, jsize);
env->DeleteGlobalRef(bufferClass);
return jobj;
}
/*
* Class: org_linphone_core_LinphoneInfoMessageImpl
* Method: getContent
......
package org.linphone.core;
/**
* The LinphoneContent object representing a data buffer.
**/
public interface LinphoneBuffer {
byte[] getContent();
void setContent(byte[] data);
int getSize();
void setSize(int size);
}
......@@ -4,9 +4,38 @@ import java.util.Vector;
public interface LinphoneChatMessage {
interface StateListener{
@Deprecated
interface StateListener {
void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state);
}
interface LinphoneChatMessageListener {
void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state);
/**
* This function is called by the core upon an incoming File transfer is started. This function may be call several time for the same file in case of large file.
* @param content incoming content information
* @param buffer holding the received data. Empty buffer means end of file.
*/
void onLinphoneChatMessageFileTransferReceived(LinphoneChatMessage msg, LinphoneContent content, LinphoneBuffer buffer);
/**
* This function is called by the core when an outgoing file transfer is started. This function is called until size is set to 0.
* @param content incoming content information
* @param offset the offset in the file from where to get the data to be sent
* @param size the number of bytes expected by the framework
* @param bufferToFill A LinphoneBuffer object holding the data written by the application. An empty buffer means end of file.
*/
void onLinphoneChatMessageFileTransferSent(LinphoneChatMessage msg, LinphoneContent content, int offset, int size, LinphoneBuffer bufferToFill);
/**
* File transfer progress indication callback prototype.
* @param content incoming content information
* @param offset The number of bytes sent/received since the beginning of the transfer.
* @param total The total number of bytes to be sent/received.
*/
void onLinphoneChatMessageFileTransferProgressChanged(LinphoneChatMessage msg, LinphoneContent content, int offset, int total);
}
public static class State {
static private Vector<State> values = new Vector<State>();
private final int mValue;
......@@ -33,6 +62,10 @@ public interface LinphoneChatMessage {
* Message was received(and acknowledged) but cannot get file from server
*/
public final static State FileTransferError = new State(4,"FileTransferError");
/**
* File transfer has been completed successfully.
*/
public final static State FileTransferDone = new State(5,"FileTransferDone");
private State(int value,String stringValue) {
mValue = value;
......@@ -158,11 +191,6 @@ public interface LinphoneChatMessage {
*/
ErrorInfo getErrorInfo();
/**
* Start the download of the file bundled in the message
*/
void startFileDownload(LinphoneChatMessage.StateListener listener);
/**
* Cancel an ongoing file transfer attached to this message.(upload or download).
*/
......@@ -184,4 +212,19 @@ public interface LinphoneChatMessage {
*/
String getAppData();
/**
* Set the path to the file to read from or write to during the file transfer.
* @param path The path to the file to use for the file transfer.
*/
void setFileTransferFilepath(String path);
/**
* Start the download of the file referenced in a LinphoneChatMessage from remote server.
*/
void downloadFile();
/**
* Set the callbacks associated with the LinphoneChatMessage.
*/
void setListener(LinphoneChatMessage.LinphoneChatMessageListener listener);
}
......@@ -44,6 +44,7 @@ public interface LinphoneChatRoom {
* Send a message to peer member of this chat room.
* @param chat message
*/
@Deprecated
void sendMessage(LinphoneChatMessage message, LinphoneChatMessage.StateListener listener);
/**
......@@ -144,4 +145,9 @@ public interface LinphoneChatRoom {
*/
LinphoneChatMessage createFileTransferMessage(LinphoneContent content);
/**
*
* @param message
*/
void sendChatMessage(LinphoneChatMessage message);
}
......@@ -145,7 +145,7 @@ abstract public class LinphoneCoreFactory {
/**
* Create a LinphoneContent object from byte array.
*/
abstract public LinphoneContent createLinphoneContent(String type, String subType,byte [] data, String encoding);
abstract public LinphoneContent createLinphoneContent(String type, String subType, byte[] data, String encoding);
/**
* Create a PresenceActivity object.
......
package org.linphone.core;
public class LinphoneBufferImpl implements LinphoneBuffer {
private byte[] mData;
private int mSize;
public LinphoneBufferImpl(byte[] data, int size)
{
mData = data;
mSize = size;
}
@Override
public byte[] getContent() {
return mData;
}
@Override
public void setContent(byte[] data) {
mData = data;
}
@Override
public int getSize() {
return mSize;
}
@Override
public void setSize(int size) {
mSize = size;
}
}
......@@ -15,6 +15,9 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage {
private native boolean isOutgoing(long ptr);
private native void store(long ptr);
private native int getStorageId(long ptr);
private native void setFileTransferFilepath(long ptr, String path);
private native void downloadFile(long ptr);
private native void setListener(long ptr, LinphoneChatMessageListener listener);
private native void unref(long ptr);
protected LinphoneChatMessageImpl(long aNativePtr) {
......@@ -113,12 +116,6 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage {
super.finalize();
}
private native void startFileDownload(long ptr, StateListener listener);
@Override
public void startFileDownload(StateListener listener) {
startFileDownload(nativePtr, listener);
}
private native Object getFileTransferInformation(long ptr);
@Override
public LinphoneContent getFileTransferInformation() {
......@@ -142,4 +139,19 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage {
public void cancelFileTransfer() {
cancelFileTransfer(nativePtr);
}
@Override
public void setFileTransferFilepath(String path) {
setFileTransferFilepath(nativePtr, path);
}
@Override
public void downloadFile() {
downloadFile(nativePtr);
}
@Override
public void setListener(LinphoneChatMessageListener listener) {
setListener(nativePtr, listener);
}
}
......@@ -21,6 +21,7 @@ package org.linphone.core;
import org.linphone.core.LinphoneChatMessage.State;
import org.linphone.core.LinphoneChatMessage.StateListener;
@SuppressWarnings("deprecation")
class LinphoneChatRoomImpl implements LinphoneChatRoom {
protected final long nativePtr;
private native long createLinphoneChatMessage(long ptr, String message);
......@@ -41,6 +42,7 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom {
private native long createLinphoneChatMessage2(long ptr, String message,
String url, int state, long timestamp, boolean isRead,
boolean isIncoming);
private native void sendChatMessage(long ptr, Object message, long messagePtr);
protected LinphoneChatRoomImpl(long aNativePtr) {
nativePtr = aNativePtr;
......@@ -176,5 +178,8 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom {
return new LinphoneChatMessageImpl(createFileTransferMessage(nativePtr, content.getName(), content.getType(), content.getSubtype(), content.getRealSize()));
}
}
@Override
public void sendChatMessage(LinphoneChatMessage message) {
sendChatMessage(nativePtr, message, ((LinphoneChatMessageImpl)message).getNativePtr());
}
}
......@@ -154,7 +154,7 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory {
@Override
public LinphoneContent createLinphoneContent(String type, String subType,
String data) {
return new LinphoneContentImpl(type,subType,data.getBytes(),null);
return new LinphoneContentImpl(type,subType,data == null ? null : data.getBytes(), null);
}
@Override
......
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