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

他这个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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值