mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-28 00:29:21 +00:00
Add JNI to access call statistics.
This commit is contained in:
parent
b67d2dd4a7
commit
c476c7ec79
8 changed files with 279 additions and 0 deletions
|
|
@ -20,6 +20,7 @@ package org.linphone.core.tutorials;
|
|||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneCallStats;
|
||||
import org.linphone.core.LinphoneChatMessage;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
|
|
@ -97,6 +98,7 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
public void globalState(LinphoneCore lc, GlobalState state, String message) {}
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {}
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {}
|
||||
public void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats) {}
|
||||
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
|
||||
public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {}
|
||||
public void notifyReceived(LinphoneCore lc, LinphoneCall call, LinphoneAddress from, byte[] event){}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.linphone.core.tutorials;
|
|||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneCallStats;
|
||||
import org.linphone.core.LinphoneChatMessage;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
|
|
@ -75,6 +76,7 @@ public class TutorialChatRoom implements LinphoneCoreListener {
|
|||
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,String url) {}
|
||||
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {}
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg){}
|
||||
public void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats) {}
|
||||
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
|
||||
public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {}
|
||||
public void notifyReceived(LinphoneCore lc, LinphoneCall call, LinphoneAddress from, byte[] event){}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.linphone.core.tutorials;
|
|||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneCallStats;
|
||||
import org.linphone.core.LinphoneChatMessage;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
|
|
@ -69,6 +70,7 @@ public class TutorialHelloWorld implements LinphoneCoreListener {
|
|||
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,String url) {}
|
||||
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {}
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {}
|
||||
public void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats) {}
|
||||
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
|
||||
public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {}
|
||||
public void notifyReceived(LinphoneCore lc, LinphoneCall call, LinphoneAddress from, byte[] event){}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.linphone.core.tutorials;
|
|||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneCallStats;
|
||||
import org.linphone.core.LinphoneChatMessage;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
|
|
@ -80,6 +81,7 @@ public class TutorialRegistration implements LinphoneCoreListener {
|
|||
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {}
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {}
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {}
|
||||
public void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats) {}
|
||||
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
|
||||
public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {}
|
||||
public void notifyReceived(LinphoneCore lc, LinphoneCall call, LinphoneAddress from, byte[] event){}
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ public:
|
|||
vTable.message_received = message_received;
|
||||
vTable.new_subscription_request = new_subscription_request;
|
||||
vTable.notify_presence_recv = notify_presence_recv;
|
||||
vTable.call_stats_updated = callStatsUpdated;
|
||||
|
||||
listenerClass = (jclass)env->NewGlobalRef(env->GetObjectClass( alistener));
|
||||
|
||||
|
|
@ -133,6 +134,9 @@ public:
|
|||
callStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCall$State"));
|
||||
callStateFromIntId = env->GetStaticMethodID(callStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCall$State;");
|
||||
|
||||
/*callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats);*/
|
||||
callStatsUpdatedId = env->GetMethodID(listenerClass, "callStatsUpdated", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCallStats;)V");
|
||||
|
||||
chatMessageStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessage$State"));
|
||||
chatMessageStateFromIntId = env->GetStaticMethodID(chatMessageStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneChatMessage$State;");
|
||||
|
||||
|
|
@ -172,6 +176,10 @@ public:
|
|||
addressClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAddressImpl"));
|
||||
addressCtrId =env->GetMethodID(addressClass,"<init>", "(J)V");
|
||||
|
||||
callStatsClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCallStatsImpl"));
|
||||
callStatsId = env->GetMethodID(callStatsClass, "<init>", "(JJ)V");
|
||||
callSetAudioStatsId = env->GetMethodID(callClass, "setAudioStats", "(Lorg/linphone/core/LinphoneCallStats;)V");
|
||||
callSetVideoStatsId = env->GetMethodID(callClass, "setVideoStats", "(Lorg/linphone/core/LinphoneCallStats;)V");
|
||||
}
|
||||
|
||||
~LinphoneCoreData() {
|
||||
|
|
@ -184,6 +192,7 @@ public:
|
|||
env->DeleteGlobalRef(globalStateClass);
|
||||
env->DeleteGlobalRef(registrationStateClass);
|
||||
env->DeleteGlobalRef(callStateClass);
|
||||
env->DeleteGlobalRef(callStatsClass);
|
||||
env->DeleteGlobalRef(chatMessageStateClass);
|
||||
env->DeleteGlobalRef(proxyClass);
|
||||
env->DeleteGlobalRef(callClass);
|
||||
|
|
@ -202,6 +211,7 @@ public:
|
|||
jmethodID notifyPresenceReceivedId;
|
||||
jmethodID textReceivedId;
|
||||
jmethodID messageReceivedId;
|
||||
jmethodID callStatsUpdatedId;
|
||||
|
||||
jclass globalStateClass;
|
||||
jmethodID globalStateId;
|
||||
|
|
@ -215,6 +225,11 @@ public:
|
|||
jmethodID callStateId;
|
||||
jmethodID callStateFromIntId;
|
||||
|
||||
jclass callStatsClass;
|
||||
jmethodID callStatsId;
|
||||
jmethodID callSetAudioStatsId;
|
||||
jmethodID callSetVideoStatsId;
|
||||
|
||||
jclass chatMessageStateClass;
|
||||
jmethodID chatMessageStateFromIntId;
|
||||
|
||||
|
|
@ -424,6 +439,24 @@ public:
|
|||
}
|
||||
|
||||
}
|
||||
static void callStatsUpdated(LinphoneCore *lc, LinphoneCall* call, const LinphoneCallStats *stats) {
|
||||
JNIEnv *env = 0;
|
||||
jobject statsobj;
|
||||
jobject callobj;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM\n");
|
||||
return;
|
||||
}
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
|
||||
statsobj = env->NewObject(lcData->callStatsClass, lcData->callStatsId, (jlong)call, (jlong)stats);
|
||||
callobj = lcData->getCall(env, call);
|
||||
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
|
||||
env->CallVoidMethod(callobj, lcData->callSetAudioStatsId, statsobj);
|
||||
else
|
||||
env->CallVoidMethod(callobj, lcData->callSetVideoStatsId, statsobj);
|
||||
env->CallVoidMethod(lcData->listener, lcData->callStatsUpdatedId, lcData->core, callobj, statsobj);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
@ -1211,6 +1244,113 @@ extern "C" jint Java_org_linphone_core_LinphoneCallLogImpl_getCallDuration(JNIEn
|
|||
return ((LinphoneCallLog*)ptr)->duration;
|
||||
}
|
||||
|
||||
/* CallStats */
|
||||
extern "C" int Java_org_linphone_core_LinphoneCallStatsImpl_getMediaType(JNIEnv *env, jobject thiz, jlong stats_ptr) {
|
||||
return (int)((LinphoneCallStats *)stats_ptr)->type;
|
||||
}
|
||||
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getSenderLossRate(JNIEnv *env, jobject thiz, jlong stats_ptr) {
|
||||
const LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr;
|
||||
const report_block_t *srb = NULL;
|
||||
|
||||
if (!stats->sent_rtcp)
|
||||
return (jfloat)0.0;
|
||||
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
|
||||
if (stats->sent_rtcp->b_cont != NULL)
|
||||
msgpullup(stats->sent_rtcp, -1);
|
||||
if (rtcp_is_SR(stats->sent_rtcp))
|
||||
srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0);
|
||||
else if (rtcp_is_RR(stats->sent_rtcp))
|
||||
srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0);
|
||||
if (!srb)
|
||||
return (jfloat)0.0;
|
||||
return (jfloat)(100.0 * report_block_get_fraction_lost(srb) / 256.0);
|
||||
}
|
||||
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getReceiverLossRate(JNIEnv *env, jobject thiz, jlong stats_ptr) {
|
||||
const LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr;
|
||||
const report_block_t *rrb = NULL;
|
||||
|
||||
if (!stats->received_rtcp)
|
||||
return (jfloat)0.0;
|
||||
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
|
||||
if (stats->received_rtcp->b_cont != NULL)
|
||||
msgpullup(stats->received_rtcp, -1);
|
||||
if (rtcp_is_RR(stats->received_rtcp))
|
||||
rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0);
|
||||
else if (rtcp_is_SR(stats->received_rtcp))
|
||||
rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0);
|
||||
if (!rrb)
|
||||
return (jfloat)0.0;
|
||||
return (jfloat)(100.0 * report_block_get_fraction_lost(rrb) / 256.0);
|
||||
}
|
||||
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getSenderInterarrivalJitter(JNIEnv *env, jobject thiz, jlong stats_ptr, jlong call_ptr) {
|
||||
LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr;
|
||||
const LinphoneCall *call = (LinphoneCall *)call_ptr;
|
||||
const LinphoneCallParams *params = linphone_call_get_current_params(call);
|
||||
const PayloadType *pt;
|
||||
const report_block_t *srb = NULL;
|
||||
|
||||
if (!stats->sent_rtcp)
|
||||
return (jfloat)0.0;
|
||||
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
|
||||
if (stats->sent_rtcp->b_cont != NULL)
|
||||
msgpullup(stats->sent_rtcp, -1);
|
||||
if (rtcp_is_SR(stats->sent_rtcp))
|
||||
srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0);
|
||||
else if (rtcp_is_RR(stats->sent_rtcp))
|
||||
srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0);
|
||||
if (!srb)
|
||||
return (jfloat)0.0;
|
||||
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
|
||||
pt = linphone_call_params_get_used_audio_codec(params);
|
||||
else
|
||||
pt = linphone_call_params_get_used_video_codec(params);
|
||||
return (jfloat)((float)report_block_get_interarrival_jitter(srb) / (float)pt->clock_rate);
|
||||
}
|
||||
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getReceiverInterarrivalJitter(JNIEnv *env, jobject thiz, jlong stats_ptr, jlong call_ptr) {
|
||||
LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr;
|
||||
const LinphoneCall *call = (LinphoneCall *)call_ptr;
|
||||
const LinphoneCallParams *params = linphone_call_get_current_params(call);
|
||||
const PayloadType *pt;
|
||||
const report_block_t *rrb = NULL;
|
||||
|
||||
if (!stats->received_rtcp)
|
||||
return (jfloat)0.0;
|
||||
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
|
||||
if (stats->received_rtcp->b_cont != NULL)
|
||||
msgpullup(stats->received_rtcp, -1);
|
||||
if (rtcp_is_SR(stats->received_rtcp))
|
||||
rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0);
|
||||
else if (rtcp_is_RR(stats->received_rtcp))
|
||||
rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0);
|
||||
if (!rrb)
|
||||
return (jfloat)0.0;
|
||||
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
|
||||
pt = linphone_call_params_get_used_audio_codec(params);
|
||||
else
|
||||
pt = linphone_call_params_get_used_video_codec(params);
|
||||
return (jfloat)((float)report_block_get_interarrival_jitter(rrb) / (float)pt->clock_rate);
|
||||
}
|
||||
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getRoundTripDelay(JNIEnv *env, jobject thiz, jlong stats_ptr) {
|
||||
return (jfloat)((LinphoneCallStats *)stats_ptr)->round_trip_delay;
|
||||
}
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallStatsImpl_getLatePacketsCumulativeNumber(JNIEnv *env, jobject thiz, jlong stats_ptr, jlong call_ptr) {
|
||||
LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr;
|
||||
LinphoneCall *call = (LinphoneCall *)call_ptr;
|
||||
rtp_stats_t rtp_stats;
|
||||
|
||||
memset(&rtp_stats, 0, sizeof(rtp_stats));
|
||||
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
|
||||
audio_stream_get_local_rtp_stats(call->audiostream, &rtp_stats);
|
||||
#ifdef VIDEO_ENABLED
|
||||
else
|
||||
video_stream_get_local_rtp_stats(call->videostream, &rtp_stats);
|
||||
#endif
|
||||
return (jlong)rtp_stats.outoftime;
|
||||
}
|
||||
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getJitterBufferSize(JNIEnv *env, jobject thiz, jlong stats_ptr) {
|
||||
return (jfloat)((LinphoneCallStats *)stats_ptr)->jitter_stats.jitter_buffer_size_ms;
|
||||
}
|
||||
|
||||
/*payloadType*/
|
||||
extern "C" jstring Java_org_linphone_core_PayloadTypeImpl_toString(JNIEnv* env,jobject thiz,jlong ptr) {
|
||||
PayloadType* pt = (PayloadType*)ptr;
|
||||
|
|
|
|||
|
|
@ -159,6 +159,30 @@ public interface LinphoneCall {
|
|||
* @Return LinphoneCallLog
|
||||
**/
|
||||
LinphoneCallLog getCallLog();
|
||||
|
||||
/**
|
||||
* Set the audio statistics associated with this call.
|
||||
* @return LinphoneCallStats
|
||||
*/
|
||||
void setAudioStats(LinphoneCallStats stats);
|
||||
|
||||
/**
|
||||
* Set the video statistics associated with this call.
|
||||
* @return LinphoneCallStats
|
||||
*/
|
||||
void setVideoStats(LinphoneCallStats stats);
|
||||
|
||||
/**
|
||||
* Get the audio statistics associated with this call.
|
||||
* @return LinphoneCallStats
|
||||
*/
|
||||
LinphoneCallStats getAudioStats();
|
||||
|
||||
/**
|
||||
* Get the video statistics associated with this call.
|
||||
* @return LinphoneCallStats
|
||||
*/
|
||||
LinphoneCallStats getVideoStats();
|
||||
|
||||
LinphoneCallParams getRemoteParams();
|
||||
|
||||
|
|
|
|||
102
java/common/org/linphone/core/LinphoneCallStats.java
Normal file
102
java/common/org/linphone/core/LinphoneCallStats.java
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
LinPhoneCallStats.java
|
||||
Copyright (C) 2010 Belledonne Communications, Grenoble, France
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
public interface LinphoneCallStats {
|
||||
static public class MediaType {
|
||||
static private Vector values = new Vector();
|
||||
/**
|
||||
* Audio
|
||||
*/
|
||||
static public MediaType Audio = new MediaType(0, "Audio");
|
||||
/**
|
||||
* Video
|
||||
*/
|
||||
static public MediaType Video = new MediaType(1, "Video");
|
||||
protected final int mValue;
|
||||
private final String mStringValue;
|
||||
|
||||
private MediaType(int value, String stringValue) {
|
||||
mValue = value;
|
||||
values.addElement(this);
|
||||
mStringValue = stringValue;
|
||||
}
|
||||
public static MediaType fromInt(int value) {
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
MediaType mtype = (MediaType) values.elementAt(i);
|
||||
if (mtype.mValue == value) return mtype;
|
||||
}
|
||||
throw new RuntimeException("MediaType not found [" + value + "]");
|
||||
}
|
||||
public String toString() {
|
||||
return mStringValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stats media type
|
||||
* @return MediaType
|
||||
*/
|
||||
public MediaType getMediaType();
|
||||
|
||||
/**
|
||||
* Get the sender loss rate since last report
|
||||
* @return The sender loss rate
|
||||
*/
|
||||
public float getSenderLossRate();
|
||||
|
||||
/**
|
||||
* Get the receiver loss rate since last report
|
||||
* @return The receiver loss rate
|
||||
*/
|
||||
public float getReceiverLossRate();
|
||||
|
||||
/**
|
||||
* Get the sender interarrival jitter
|
||||
* @return The interarrival jitter at last emitted sender report
|
||||
*/
|
||||
public float getSenderInterarrivalJitter();
|
||||
|
||||
/**
|
||||
* Get the receiver interarrival jitter
|
||||
* @return The interarrival jitter at last received receiver report
|
||||
*/
|
||||
public float getReceiverInterarrivalJitter();
|
||||
|
||||
/**
|
||||
* Get the round trip delay
|
||||
* @return The round trip delay in seconds, -1 if the information is not available
|
||||
*/
|
||||
public float getRoundTripDelay();
|
||||
|
||||
/**
|
||||
* Get the cumulative number of late packets
|
||||
* @return The cumulative number of late packets
|
||||
*/
|
||||
public long getLatePacketsCumulativeNumber();
|
||||
|
||||
/**
|
||||
* Get the jitter buffer size
|
||||
* @return The jitter buffer size in milliseconds
|
||||
*/
|
||||
public float getJitterBufferSize();
|
||||
}
|
||||
|
|
@ -40,6 +40,11 @@ public interface LinphoneCoreListener {
|
|||
* */
|
||||
void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message);
|
||||
|
||||
/**
|
||||
* Call stats notification
|
||||
*/
|
||||
void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats);
|
||||
|
||||
/**
|
||||
* Callback to display change in encryption state.
|
||||
* @param encrypted true if all streams of the call are encrypted
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue