他这个debug机制, 我觉得很niubility.
介绍
Linphone有自己的一套Log日志系统, 其中我们也可以自定义一些Log日志. 其中在LinphoneService中实现LinphoneLogHandler类,并实现未实现的方法, 就可以自定义Linphone的Log输出了.
本片文章主要是对linphone的追踪过程. 整个过程时从xml配置文件到java, 再从java到jni, 再到java, 的一个代码追踪过程.
如果您有什么不懂的话, 可以随时评论. 一些问题也可以问我. 非常乐意回答. [笑脸]
配置文件下控制的Debug
具体位置
[Setting -> Advanced -> Debug] 打对
调用配置文件
LinphonePreferrence.java
public boolean isDebugEnabled() {
return getConfig().getBool("app", "debug", false);
}
public void setBackgroundModeEnabled(boolean enabled) {
getConfig().setBool("app", "background_mode", enabled);
}
找到LinphoneService使用debug配置文件
/data/data/org.linphone/file/.linphonerc
其中.linphonerc中有个点
找到LinphoneCoreFactoryImpl.java中
@Override
public native void enableLogCollection(boolean enable);
@Override
public native void setLogCollectionPath(String path);
找到linphonecore_jni.cc
extern "C" void Java_org_linphone_core_LinphoneCoreFactoryImpl_enableLogCollection(JNIEnv* env
,jobject thiz
,jboolean enable) {
linphone_core_enable_log_collection(enable ? LinphoneLogCollectionEnabledWithoutPreviousLogHandler : LinphoneLogCollectionDisabled);
}
其中
/**
* @ingroup initializing
*/
typedef enum _LinphoneLogCollectionState {
LinphoneLogCollectionDisabled,
LinphoneLogCollectionEnabled,
LinphoneLogCollectionEnabledWithoutPreviousLogHandler
} LinphoneLogCollectionState;
找到linphonecore.c
void linphone_core_enable_log_collection(LinphoneLogCollectionState state) {
if (liblinphone_log_collection_state == state) return;
/* at first call of this function, set liblinphone_log_func to the current
* ortp log function */
if( liblinphone_log_func == NULL ){
liblinphone_log_func = ortp_get_log_handler();
}
liblinphone_log_collection_state = state;
if (state != LinphoneLogCollectionDisabled) {
ortp_mutex_init(&liblinphone_log_collection_mutex, NULL);
if (state == LinphoneLogCollectionEnabledWithoutPreviousLogHandler) {
liblinphone_log_func = NULL;
} else {
liblinphone_log_func = ortp_get_log_handler();
}
ortp_set_log_handler(linphone_core_log_collection_handler);
} else {
ortp_set_log_handler(liblinphone_log_func);
}
}
当enable为true的时候, state==LinphoneLogCollectionEnabledWithoutPreviousLogHandler, 此时执行
if (state != LinphoneLogCollectionDisabled) {
找到linphone_core_set_log_handler
void linphone_core_set_log_handler(OrtpLogFunc logfunc) {
if (ortp_get_log_handler() == linphone_core_log_collection_handler) {
ms_message("There is already a log collection handler, keep it");
liblinphone_log_func = logfunc;
} else
ortp_set_log_handler(logfunc);
}
void linphone_core_enable_logs_with_cb(OrtpLogFunc logfunc){
linphone_core_set_log_level(ORTP_MESSAGE);
linphone_core_set_log_handler(logfunc);
}
linphone/coreapi/linphonecore_jni.cc: linphone_core_enable_logs_with_cb(linphone_android_ortp_log_handler);
linphone/coreapi/linphonecore_jni.cc: linphone_core_enable_logs_with_cb(linphone_android_ortp_log_handler);
找着找着又回到了linphonecore_jni.c中
extern "C" void setAndroidLogHandler() {
linphone_core_enable_logs_with_cb(linphone_android_ortp_log_handler);
}
//LinphoneFactory
extern "C" void Java_org_linphone_core_LinphoneCoreFactoryImpl_setDebugMode(JNIEnv* env
,jobject thiz
,jboolean isDebug
,jstring jdebugTag) {
if (isDebug) {
LogDomain = GetStringUTFChars(env, jdebugTag);
linphone_core_enable_logs_with_cb(linphone_android_ortp_log_handler);
} else {
linphone_core_disable_logs();
}
}
通过*_setDebugMode追踪到LinphoneService中
也就是刚开始设置xml配置文件的那段代码
设置函数linphone_android_ortp_log_handler()
static void linphone_android_ortp_log_handler(const char *domain, OrtpLogLevel lev, const char *fmt, va_list args) {
char str[4096];
const char *levname = "undef";
vsnprintf(str, sizeof(str) - 1, fmt, args);
str[sizeof(str) - 1] = '\0';
int prio;
switch(lev) {
case ORTP_DEBUG: prio = ANDROID_LOG_DEBUG; levname="debug"; break;
case ORTP_MESSAGE: prio = ANDROID_LOG_INFO; levname="message"; break;
case ORTP_WARNING: prio = ANDROID_LOG_WARN; levname="warning"; break;
case ORTP_ERROR: prio = ANDROID_LOG_ERROR; levname="error"; break;
case ORTP_FATAL: prio = ANDROID_LOG_FATAL; levname="fatal"; break;
default: prio = ANDROID_LOG_DEFAULT; break;
}
if (handler_obj) {
JNIEnv *env = ms_get_jni_env();
jstring jdomain = env->NewStringUTF(LogDomain);
jstring jlevname = env->NewStringUTF(levname);
jstring jstr = env->NewStringUTF(str);
env->CallVoidMethod(handler_obj, loghandler_id, jdomain, (jint)lev, jlevname, jstr, NULL);
if (jdomain) env->DeleteLocalRef(jdomain);
if (jlevname) env->DeleteLocalRef(jlevname);
if (jstr) env->DeleteLocalRef(jstr);
} else {
linphone_android_log_handler(prio, str);
}
}
找到了,好兴奋
此时, 如果handler_obj不为空的话, 就是使用自定义的那个方法. 如果时NULL的话, 则使用已经定义好的log系统.
有个疑问:linphone_core_disable_logs()追踪
怎么个情况
void linphone_core_disable_logs(void){
linphone_core_set_log_level(ORTP_ERROR);
}
void linphone_core_set_log_level(OrtpLogLevel loglevel) {
OrtpLogLevel mask = loglevel;
switch (loglevel) {
case ORTP_TRACE:
case ORTP_DEBUG:
mask |= ORTP_DEBUG;
case ORTP_MESSAGE:
mask |= ORTP_MESSAGE;
case ORTP_WARNING:
mask |= ORTP_WARNING;
case ORTP_ERROR:
mask |= ORTP_ERROR;
case ORTP_FATAL:
mask |= ORTP_FATAL;
break;
case ORTP_LOGLEV_END:
break;
}
linphone_core_set_log_level_mask(mask);
}
void linphone_core_set_log_level_mask(unsigned int loglevel) {
ortp_set_log_level_mask(NULL, loglevel);
bctbx_set_log_level_mask(NULL, loglevel);
if (loglevel == 0) {
sal_disable_log();
} else {
sal_enable_log();
}
}
handler_obj哪里实现自定义
JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreFactoryImpl__1setLogHandler(JNIEnv *env, jobject jfactory, jobject jhandler) {
if (handler_obj) {
env->DeleteGlobalRef(handler_obj);
handler_obj = NULL;
}
if (jhandler) {
handler_class = (jclass) env->GetObjectClass(jhandler);
loghandler_id = env->GetMethodID(handler_class, "log", "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V");
if (loghandler_id == NULL) {
ms_fatal("log method not found");
}
handler_obj = env->NewGlobalRef(jhandler);
}
}
终于找到了, 是LinphoneLogHandler
private native void _setLogHandler(Object handler);
@Override
public void setLogHandler(LinphoneLogHandler handler) {
_setLogHandler(handler);
}
在LinphoneService中实现,就可以使用自定义的Log日志系统了
// onCreate中使用
LinphoneCoreFactory.instance().setLogHandler(new LinphoneLogHandler() {
@Override
public void log(String loggerName, int level, String levelString, String msg, Throwable e) {
System.out.println("I have a dream.");
}
});
-----------------------------------
转载于:https://blog.51cto.com/u_11797608/6370637