Linphone3.2.5 debug机制 自定义log日志

来源:互联网 发布:python 编码转换 编辑:程序博客网 时间:2024/06/03 19:54

他这个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);}
//LinphoneFactoryextern "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.");    }});
0 0