Interpreting the implementation of the android Log Mechanism: (3) Writing Device Files in JNI and C/C ++ Domains

Source: Internet
Author: User

Interpreting the implementation of the android Log Mechanism: (3) Writing Device Files in JNI and C/C ++ Domains

Tian haili @ csdn

 

Android provides a user-level lightweight Log Mechanism. Its implementation runs through Java, JNI, local C/C ++ implementation, Linux kernel driver, and Other Android layers, it is simple and clear enough to explain the case. This series of articles explains the internal implementation mechanism of the log mechanism. This article is part 3 of this series, interpreting android. util. the JNI Implementation of log, and how to operate the device file to write log information in the local implementation of C/C ++.

 

JNI Implementation of log-like

As mentioned above, Android. util. log has two native methods, which must be implemented in C/C ++ through JNI.

public static native boolean isLoggable(String tag, int level);public static native int println_native(int bufID,            int priority, String tag, String msg);

These two methods are implemented in frameworks/base/CORE/JNI/android_util_log.cpp. How to Implement JNI is not described here. However, these two methods are transferred to the call of the following two C/C ++ functions.

static jboolean android_util_Log_isLoggable(JNIEnv* env, jobject clazz, jstring tag, jint level)static jint android_util_Log_println_native(JNIEnv* env, jobject clazz,        jint bufID, jint priority, jstring tagObj, jstring msgObj)

 

Implementation of isloggable ()

The implementation of isloggable is a comparison between <level> (from the parameter) and the "log. tag. the value of <tag> "(<tag> from parameter) is record if it is greater than or equal. The program implementation snippets are as follows:

    // LOG_NAMESPACE : “log.tag.”    // chars: convert from param<tag>    strncpy(key, LOG_NAMESPACE, sizeof(LOG_NAMESPACE)-1);    strcpy(key + sizeof(LOG_NAMESPACE) - 1, chars);      len = property_get(key, buf, "");    int logLevel = toLevel(buf);    return (logLevel >= 0 && level >= logLevel) ? true : false;

 

Println_native () Implementation

FunctionAndroid_util_log_println_native ()[File android_util.log.cpp] called_ Android_log_buf_write ()[File System/CORE/liblog/logd_write.c]._ Android_log_buf_write ()The parameters are organized and called again.Write_to_logThis function pointer.

Write_to_logThis function pointer is the key to implementation.

See the definition of write_to_log:

static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;

Write_to_logInitially, it points to the function _ write_to_log_init. Therefore, when write_to_log is executed for the first time, _ write_to_log_init () is executed (). If write_to_log is not executed for the first time, it has been modified in _ write_to_log_init () to point to _ write_to_log_kernel ().

First look_ Write_to_log_init() Implementation:

static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr){#ifdef HAVE_PTHREADS    pthread_mutex_lock(&log_init_lock);#endif    if (write_to_log == __write_to_log_init) {        log_fds[LOG_ID_MAIN] = log_open("/dev/"LOGGER_LOG_MAIN, O_WRONLY);        log_fds[LOG_ID_RADIO] = log_open("/dev/"LOGGER_LOG_RADIO, O_WRONLY);        log_fds[LOG_ID_EVENTS] = log_open("/dev/"LOGGER_LOG_EVENTS, O_WRONLY);        log_fds[LOG_ID_SYSTEM] = log_open("/dev/"LOGGER_LOG_SYSTEM, O_WRONLY);        write_to_log = __write_to_log_kernel;        if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0 ||                log_fds[LOG_ID_EVENTS] < 0) {            log_close(log_fds[LOG_ID_MAIN]);            log_close(log_fds[LOG_ID_RADIO]);            log_close(log_fds[LOG_ID_EVENTS]);            log_fds[LOG_ID_MAIN] = -1;            log_fds[LOG_ID_RADIO] = -1;            log_fds[LOG_ID_EVENTS] = -1;            write_to_log = __write_to_log_null;        }        if (log_fds[LOG_ID_SYSTEM] < 0) {            log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN];        }    }#ifdef HAVE_PTHREADS    pthread_mutex_unlock(&log_init_lock);#endif    return write_to_log(log_id, vec, nr);}

Basically, mutual access protection is implemented. If it is the first call (write_to_log also points to _ write_to_log_init (), the corresponding device file is opened to obtain the descriptor, and point write_to_log to _ write_to_log_kernel (). Then, write the file in _ write_to_log_kernel.

Look at the implementation of _ write_to_kernel (), which is basically a write operation:

static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr){    ssize_t ret;    int log_fd;    if (/*(int)log_id >= 0 &&*/ (int)log_id < (int)LOG_ID_MAX) {        log_fd = log_fds[(int)log_id];    } else {        return EBADF;    }    do {        ret = log_writev(log_fd, vec, nr);    } while (ret < 0 && errno == EINTR);    return ret;}

 

To sum up, the println_native () operation is to open the device file (if it has not been opened) and then write data. But how to write it depends on the implementation of the logger driver of the log device.

 

[This series of articles]

Interpreting the implementation of the android Log Mechanism: (1) implementation architecture of log

Interpret the implementation architecture of the log mechanism.

Interpreting the implementation of the android Log Mechanism: (2) Java domain output log

Explain how the android Java program outputs log information to the log system.

Interpreting the implementation of the android Log Mechanism: (3) Writing Device Files in JNI and native Domains

Interpret the JNI Implementation of Android. util. log and how to operate the device file to write log information in the local implementation of C/C ++.

Interpreting the implementation of the android Log Mechanism: (4) Log Device-driven Logger

Interpret the implementation of the device driver logger in the Linux kernel. Logger is a misc Driver written by Android for Linux. It uses cyclic queues to implement readers/writers. Logger is the core of the implementation of the entire log mechanism.

Interpreting the implementation of the android Log Mechanism: (5) Obtaining the log program logcat

Explains how the application logcat obtains log information through open ()/select ()/read () of the device file.

Interpreting the implementation of the android Log Mechanism: (6) using log in the C/C ++ domain

This article explains how to use the Log Mechanism in the C/C ++ program of Android to record log information.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.