// INFO, 如果定义了LOG_TAG则使用LOG_TAG,否则为空,default是INFO
int __android_log_is_loggable(int prio, const char* tag, int default_prio) {
auto len = tag ? strlen(tag) : 0;
return __android_log_is_loggable_len(prio, tag, len, default_prio);
}
int __android_log_is_loggable_len(int prio, const char* tag, size_t len, int default_prio) {
// 默认是比verbose还小的
int minimum_log_priority = __android_log_get_minimum_priority();
// first_stage_init阶段,这里返回的为-1
int property_log_level = __android_log_level(tag, len);
if (property_log_level >= 0 && minimum_log_priority != ANDROID_LOG_DEFAULT) {
return prio >= std::min(property_log_level, minimum_log_priority);
} else if (property_log_level >= 0) {
return prio >= property_log_level;
} else if (minimum_log_priority != ANDROID_LOG_DEFAULT) {
return prio >= minimum_log_priority;
} else {
// 所以最终走这里,要大于等于INFO,所以first_stage_init阶段,VERBOSE和DEBUG的log可能不会打印出来
return prio >= default_prio;
}
}
// tag为null,len为0
static int __android_log_level(const char* tag, size_t len) {
/* sizeof() is used on this array below */
static const char log_namespace[] = "persist.log.tag.";
static const size_t base_offset = 8; /* skip "persist." */
if (tag == nullptr || len == 0) {
// 默认是进程名字
auto& tag_string = GetDefaultTag();
tag = tag_string.c_str();
len = tag_string.size();
}
/* sizeof(log_namespace) = strlen(log_namespace) + 1 */
char key[sizeof(log_namespace) + len];
char* kp;
size_t i;
char c = 0;
/*
* Single layer cache of four properties. Priorities are:
* log.tag.<tag>
* persist.log.tag.<tag>
* log.tag
* persist.log.tag
* Where the missing tag matches all tags and becomes the
* system global default. We do not support ro.log.tag* .
*/
static char* last_tag;
static size_t last_tag_len;
static uint32_t global_serial;
/* some compilers erroneously see uninitialized use. !not_locked */
uint32_t current_global_serial = 0;
static struct cache_char tag_cache[2];
static struct cache_char global_cache[2];
int change_detected;
int global_change_detected;
int not_locked;
strcpy(key, log_namespace);
// 为0,则获取到锁了
global_change_detected = change_detected = not_locked = lock();
// 获取到锁了
if (!not_locked) {
/*
* check all known serial numbers to changes.
*/
for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
// 第一次的时候,cache->pinfo为null,所以为false,change_detected为0
if (check_cache(&tag_cache[i].cache)) {
change_detected = 1;
}
}
for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
// 第一次的时候,其为false,global_change_detected还是0
if (check_cache(&global_cache[i].cache)) {
global_change_detected = 1;
}
}
// 在first_stage_init阶段,还没有初始化property,所以这里为-1
current_global_serial = __system_property_area_serial();
// 所以第一次的时候,这里是不相等的,所以为1
if (current_global_serial != global_serial) {
change_detected = 1;
global_change_detected = 1;
}
}
if (len) {
int local_change_detected = change_detected;
if (!not_locked) {
// 第一次last_tag为null
if (!last_tag || !last_tag[0] || (last_tag[0] != tag[0]) ||
strncmp(last_tag + 1, tag + 1, last_tag_len - 1)) {
/* invalidate log.tag.<tag> cache */
for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
// 初始化tag_cache
tag_cache[i].cache.pinfo = NULL;
tag_cache[i].c = ‘\0‘;
}
if (last_tag) last_tag[0] = ‘\0‘;
local_change_detected = 1;
}
if (!last_tag || !last_tag[0]) {
if (!last_tag) {
// 第一次就进行分配了
last_tag = static_cast<char*>(calloc(1, len + 1));
last_tag_len = 0;
if (last_tag) last_tag_len = len + 1;
} else if (len >= last_tag_len) {
last_tag = static_cast<char*>(realloc(last_tag, len + 1));
last_tag_len = 0;
if (last_tag) last_tag_len = len + 1;
}
if (last_tag) {
// 将tag拷贝到last_tag上
strncpy(last_tag, tag, len);
last_tag[len] = ‘\0‘;
}
}
}
// 组合persist.log.tag.TAGNAME
strncpy(key + sizeof(log_namespace) - 1, tag, len);
key[sizeof(log_namespace) - 1 + len] = ‘\0‘;
kp = key;
for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
struct cache_char* cache = &tag_cache[i];
struct cache_char temp_cache;
// 第一次不走这里
if (not_locked) {
temp_cache.cache.pinfo = NULL;
temp_cache.c = ‘\0‘;
cache = &temp_cache;
}
// 走这里,local_change_detected为1了
if (local_change_detected) {
refresh_cache(cache, kp);
}
// ‘\0‘为false的,不会走这里
if (cache->c) {
c = cache->c;
break;
}
// 去掉persist,再来一次
kp = key + base_offset;
}
}
switch (toupper(c)) { /* if invalid, resort to global */
case ‘V‘:
case ‘D‘:
case ‘I‘:
case ‘W‘:
case ‘E‘:
case ‘F‘: /* Not officially supported */
case ‘A‘:
case ‘S‘:
case BOOLEAN_FALSE: /* Not officially supported */
break;
default:
/* clear ‘.‘ after log.tag */
key[sizeof(log_namespace) - 2] = ‘\0‘;
kp = key;
// 和上面是差不多的
for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
struct cache_char* cache = &global_cache[i];
struct cache_char temp_cache;
if (not_locked) {
temp_cache = *cache;
if (temp_cache.cache.pinfo != cache->cache.pinfo) { /* check atomic */
temp_cache.cache.pinfo = NULL;
temp_cache.c = ‘\0‘;
}
cache = &temp_cache;
}
if (global_change_detected) {
refresh_cache(cache, kp);
}
if (cache->c) {
c = cache->c;
break;
}
kp = key + base_offset;
}
break;
}
if (!not_locked) {
global_serial = current_global_serial;
unlock();
}
switch (toupper(c)) {
/* clang-format off */
case ‘V‘: return ANDROID_LOG_VERBOSE;
case ‘D‘: return ANDROID_LOG_DEBUG;
case ‘I‘: return ANDROID_LOG_INFO;
case ‘W‘: return ANDROID_LOG_WARN;
case ‘E‘: return ANDROID_LOG_ERROR;
case ‘F‘: /* FALLTHRU */ /* Not officially supported */
case ‘A‘: return ANDROID_LOG_FATAL;
case BOOLEAN_FALSE: /* FALLTHRU */ /* Not Officially supported */
case ‘S‘: return ANDROID_LOG_SILENT;
/* clang-format on */
}
// 所以在fist_stage_init阶段,这里返回的是-1
return -1;
}
static int check_cache(struct cache* cache) {
return cache->pinfo && __system_property_serial(cache->pinfo) != cache->serial;
}
static void refresh_cache(struct cache_char* cache, const char* key) {
char buf[PROP_VALUE_MAX];
if (!cache->cache.pinfo) {
cache->cache.pinfo = __system_property_find(key);
if (!cache->cache.pinfo) {
// first_stag_init的时候,cache都是为NULL的,所以,直接返回了
return;
}
}
cache->cache.serial = __system_property_serial(cache->cache.pinfo);
__system_property_read(cache->cache.pinfo, 0, buf);
switch (buf[0]) {
case ‘t‘:
case ‘T‘:
cache->c = strcasecmp(buf + 1, "rue") ? buf[0] : BOOLEAN_TRUE;
break;
case ‘f‘:
case ‘F‘:
cache->c = strcasecmp(buf + 1, "alse") ? buf[0] : BOOLEAN_FALSE;
break;
default:
cache->c = buf[0];
}
}
原文:https://www.cnblogs.com/pyjetson/p/14879076.html