Merge "liblog: Add private interfaces for buffer size properties" am: 094004bf42
am: 8806766621
Change-Id: I99f9632892f2afa34d124d9f8366fc1a0b13fc09
This commit is contained in:
commit
eb980356fe
2 changed files with 320 additions and 47 deletions
|
@ -21,6 +21,7 @@
|
|||
|
||||
/* Android private interfaces */
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
@ -132,6 +133,20 @@ int __android_log_security(); /* Device Owner is present */
|
|||
|
||||
int __android_log_is_debuggable();
|
||||
|
||||
#define BOOL_DEFAULT_FLAG_TRUE_FALSE 0x1
|
||||
#define BOOL_DEFAULT_FALSE 0x0 /* false if property not present */
|
||||
#define BOOL_DEFAULT_TRUE 0x1 /* true if property not present */
|
||||
#define BOOL_DEFAULT_FLAG_PERSIST 0x2 /* <key>, persist.<key>, ro.<key> */
|
||||
#define BOOL_DEFAULT_FLAG_ENG 0x4 /* off for user */
|
||||
#define BOOL_DEFAULT_FLAG_SVELTE 0x8 /* off for low_ram */
|
||||
bool __android_logger_property_get_bool(const char *key, int flag);
|
||||
|
||||
#define LOG_BUFFER_SIZE (256 * 1024) /* Tuned with ro.logd.size per-platform */
|
||||
#define LOG_BUFFER_MIN_SIZE (64 * 1024UL)
|
||||
#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL)
|
||||
unsigned long __android_logger_get_buffer_size(log_id_t logId);
|
||||
bool __android_logger_valid_buffer_size(unsigned long value);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,12 +16,16 @@
|
|||
|
||||
#include <ctype.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
|
||||
#include <sys/_system_properties.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <android/log.h>
|
||||
#include <log/logger.h>
|
||||
#include <private/android_logger.h>
|
||||
|
||||
#include "log_portability.h"
|
||||
|
||||
|
@ -47,12 +51,16 @@ static void unlock()
|
|||
}
|
||||
|
||||
struct cache {
|
||||
const prop_info *pinfo;
|
||||
const prop_info* pinfo;
|
||||
uint32_t serial;
|
||||
};
|
||||
|
||||
struct cache_char {
|
||||
struct cache cache;
|
||||
unsigned char c;
|
||||
};
|
||||
|
||||
static int check_cache(struct cache *cache)
|
||||
static int check_cache(struct cache* cache)
|
||||
{
|
||||
return cache->pinfo
|
||||
&& __system_property_serial(cache->pinfo) != cache->serial;
|
||||
|
@ -61,18 +69,18 @@ static int check_cache(struct cache *cache)
|
|||
#define BOOLEAN_TRUE 0xFF
|
||||
#define BOOLEAN_FALSE 0xFE
|
||||
|
||||
static void refresh_cache(struct cache *cache, const char *key)
|
||||
static void refresh_cache(struct cache_char* cache, const char* key)
|
||||
{
|
||||
char buf[PROP_VALUE_MAX];
|
||||
|
||||
if (!cache->pinfo) {
|
||||
cache->pinfo = __system_property_find(key);
|
||||
if (!cache->pinfo) {
|
||||
if (!cache->cache.pinfo) {
|
||||
cache->cache.pinfo = __system_property_find(key);
|
||||
if (!cache->cache.pinfo) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
cache->serial = __system_property_serial(cache->pinfo);
|
||||
__system_property_read(cache->pinfo, 0, buf);
|
||||
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;
|
||||
|
@ -85,7 +93,7 @@ static void refresh_cache(struct cache *cache, const char *key)
|
|||
}
|
||||
}
|
||||
|
||||
static int __android_log_level(const char *tag, size_t len, int default_prio)
|
||||
static int __android_log_level(const char* tag, size_t len, int default_prio)
|
||||
{
|
||||
/* sizeof() is used on this array below */
|
||||
static const char log_namespace[] = "persist.log.tag.";
|
||||
|
@ -93,8 +101,8 @@ static int __android_log_level(const char *tag, size_t len, int default_prio)
|
|||
/* calculate the size of our key temporary buffer */
|
||||
const size_t taglen = tag ? len : 0;
|
||||
/* sizeof(log_namespace) = strlen(log_namespace) + 1 */
|
||||
char key[sizeof(log_namespace) + taglen]; /* may be > PROPERTY_KEY_MAX */
|
||||
char *kp;
|
||||
char key[sizeof(log_namespace) + taglen]; /* may be > PROP_NAME_MAX */
|
||||
char* kp;
|
||||
size_t i;
|
||||
char c = 0;
|
||||
/*
|
||||
|
@ -110,8 +118,8 @@ static int __android_log_level(const char *tag, size_t len, int default_prio)
|
|||
static uint32_t global_serial;
|
||||
/* some compilers erroneously see uninitialized use. !not_locked */
|
||||
uint32_t current_global_serial = 0;
|
||||
static struct cache tag_cache[2];
|
||||
static struct cache global_cache[2];
|
||||
static struct cache_char tag_cache[2];
|
||||
static struct cache_char global_cache[2];
|
||||
int change_detected;
|
||||
int global_change_detected;
|
||||
int not_locked;
|
||||
|
@ -125,12 +133,12 @@ static int __android_log_level(const char *tag, size_t len, int default_prio)
|
|||
* check all known serial numbers to changes.
|
||||
*/
|
||||
for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
|
||||
if (check_cache(&tag_cache[i])) {
|
||||
if (check_cache(&tag_cache[i].cache)) {
|
||||
change_detected = 1;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
|
||||
if (check_cache(&global_cache[i])) {
|
||||
if (check_cache(&global_cache[i].cache)) {
|
||||
global_change_detected = 1;
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +162,7 @@ static int __android_log_level(const char *tag, size_t len, int default_prio)
|
|||
|| ((len < sizeof(last_tag)) && last_tag[len])) {
|
||||
/* invalidate log.tag.<tag> cache */
|
||||
for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
|
||||
tag_cache[i].pinfo = NULL;
|
||||
tag_cache[i].cache.pinfo = NULL;
|
||||
tag_cache[i].c = '\0';
|
||||
}
|
||||
last_tag[0] = '\0';
|
||||
|
@ -174,11 +182,11 @@ static int __android_log_level(const char *tag, size_t len, int default_prio)
|
|||
|
||||
kp = key;
|
||||
for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
|
||||
struct cache *cache = &tag_cache[i];
|
||||
struct cache temp_cache;
|
||||
struct cache_char* cache = &tag_cache[i];
|
||||
struct cache_char temp_cache;
|
||||
|
||||
if (not_locked) {
|
||||
temp_cache.pinfo = NULL;
|
||||
temp_cache.cache.pinfo = NULL;
|
||||
temp_cache.c = '\0';
|
||||
cache = &temp_cache;
|
||||
}
|
||||
|
@ -212,13 +220,13 @@ static int __android_log_level(const char *tag, size_t len, int default_prio)
|
|||
|
||||
kp = key;
|
||||
for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
|
||||
struct cache *cache = &global_cache[i];
|
||||
struct cache temp_cache;
|
||||
struct cache_char* cache = &global_cache[i];
|
||||
struct cache_char temp_cache;
|
||||
|
||||
if (not_locked) {
|
||||
temp_cache = *cache;
|
||||
if (temp_cache.pinfo != cache->pinfo) { /* check atomic */
|
||||
temp_cache.pinfo = NULL;
|
||||
if (temp_cache.cache.pinfo != cache->cache.pinfo) { /* check atomic */
|
||||
temp_cache.cache.pinfo = NULL;
|
||||
temp_cache.c = '\0';
|
||||
}
|
||||
cache = &temp_cache;
|
||||
|
@ -257,7 +265,7 @@ static int __android_log_level(const char *tag, size_t len, int default_prio)
|
|||
}
|
||||
|
||||
LIBLOG_ABI_PUBLIC int __android_log_is_loggable_len(int prio,
|
||||
const char *tag, size_t len,
|
||||
const char* tag, size_t len,
|
||||
int default_prio)
|
||||
{
|
||||
int logLevel = __android_log_level(tag, len, default_prio);
|
||||
|
@ -265,7 +273,7 @@ LIBLOG_ABI_PUBLIC int __android_log_is_loggable_len(int prio,
|
|||
}
|
||||
|
||||
LIBLOG_ABI_PUBLIC int __android_log_is_loggable(int prio,
|
||||
const char *tag,
|
||||
const char* tag,
|
||||
int default_prio)
|
||||
{
|
||||
int logLevel = __android_log_level(tag,
|
||||
|
@ -277,18 +285,18 @@ LIBLOG_ABI_PUBLIC int __android_log_is_loggable(int prio,
|
|||
LIBLOG_ABI_PRIVATE int __android_log_is_debuggable()
|
||||
{
|
||||
static uint32_t serial;
|
||||
static struct cache tag_cache;
|
||||
static struct cache_char tag_cache;
|
||||
static const char key[] = "ro.debuggable";
|
||||
int ret;
|
||||
|
||||
if (tag_cache.c) { /* ro property does not change after set */
|
||||
ret = tag_cache.c == '1';
|
||||
} else if (lock()) {
|
||||
struct cache temp_cache = { NULL, -1, '\0' };
|
||||
struct cache_char temp_cache = { { NULL, -1 }, '\0' };
|
||||
refresh_cache(&temp_cache, key);
|
||||
ret = temp_cache.c == '1';
|
||||
} else {
|
||||
int change_detected = check_cache(&tag_cache);
|
||||
int change_detected = check_cache(&tag_cache.cache);
|
||||
uint32_t current_serial = __system_property_area_serial();
|
||||
if (current_serial != serial) {
|
||||
change_detected = 1;
|
||||
|
@ -310,17 +318,17 @@ LIBLOG_ABI_PRIVATE int __android_log_is_debuggable()
|
|||
* Since a change is rare, we will accept a trylock failure gracefully.
|
||||
* Use a separate lock from is_loggable to keep contention down b/25563384.
|
||||
*/
|
||||
struct cache2 {
|
||||
struct cache2_char {
|
||||
pthread_mutex_t lock;
|
||||
uint32_t serial;
|
||||
const char *key_persist;
|
||||
struct cache cache_persist;
|
||||
const char *key_ro;
|
||||
struct cache cache_ro;
|
||||
unsigned char (*const evaluate)(const struct cache2 *self);
|
||||
const char* key_persist;
|
||||
struct cache_char cache_persist;
|
||||
const char* key_ro;
|
||||
struct cache_char cache_ro;
|
||||
unsigned char (*const evaluate)(const struct cache2_char *self);
|
||||
};
|
||||
|
||||
static inline unsigned char do_cache2(struct cache2 *self)
|
||||
static inline unsigned char do_cache2_char(struct cache2_char *self)
|
||||
{
|
||||
uint32_t current_serial;
|
||||
int change_detected;
|
||||
|
@ -331,8 +339,8 @@ static inline unsigned char do_cache2(struct cache2 *self)
|
|||
return self->evaluate(self);
|
||||
}
|
||||
|
||||
change_detected = check_cache(&self->cache_persist)
|
||||
|| check_cache(&self->cache_ro);
|
||||
change_detected = check_cache(&self->cache_persist.cache)
|
||||
|| check_cache(&self->cache_ro.cache);
|
||||
current_serial = __system_property_area_serial();
|
||||
if (current_serial != self->serial) {
|
||||
change_detected = 1;
|
||||
|
@ -349,7 +357,7 @@ static inline unsigned char do_cache2(struct cache2 *self)
|
|||
return c;
|
||||
}
|
||||
|
||||
static unsigned char evaluate_persist_ro(const struct cache2 *self)
|
||||
static unsigned char evaluate_persist_ro(const struct cache2_char *self)
|
||||
{
|
||||
unsigned char c = self->cache_persist.c;
|
||||
|
||||
|
@ -366,17 +374,17 @@ static unsigned char evaluate_persist_ro(const struct cache2 *self)
|
|||
*/
|
||||
LIBLOG_ABI_PUBLIC clockid_t android_log_clockid()
|
||||
{
|
||||
static struct cache2 clockid = {
|
||||
static struct cache2_char clockid = {
|
||||
PTHREAD_MUTEX_INITIALIZER,
|
||||
0,
|
||||
"persist.logd.timestamp",
|
||||
{ NULL, -1, '\0' },
|
||||
{ { NULL, -1 }, '\0' },
|
||||
"ro.logd.timestamp",
|
||||
{ NULL, -1, '\0' },
|
||||
{ { NULL, -1 }, '\0' },
|
||||
evaluate_persist_ro
|
||||
};
|
||||
|
||||
return (tolower(do_cache2(&clockid)) == 'm')
|
||||
return (tolower(do_cache2_char(&clockid)) == 'm')
|
||||
? CLOCK_MONOTONIC
|
||||
: CLOCK_REALTIME;
|
||||
}
|
||||
|
@ -385,7 +393,7 @@ LIBLOG_ABI_PUBLIC clockid_t android_log_clockid()
|
|||
* Security state generally remains constant, but the DO must be able
|
||||
* to turn off logging should it become spammy after an attack is detected.
|
||||
*/
|
||||
static unsigned char evaluate_security(const struct cache2 *self)
|
||||
static unsigned char evaluate_security(const struct cache2_char *self)
|
||||
{
|
||||
unsigned char c = self->cache_ro.c;
|
||||
|
||||
|
@ -394,15 +402,265 @@ static unsigned char evaluate_security(const struct cache2 *self)
|
|||
|
||||
LIBLOG_ABI_PUBLIC int __android_log_security()
|
||||
{
|
||||
static struct cache2 security = {
|
||||
static struct cache2_char security = {
|
||||
PTHREAD_MUTEX_INITIALIZER,
|
||||
0,
|
||||
"persist.logd.security",
|
||||
{ NULL, -1, BOOLEAN_FALSE },
|
||||
{ { NULL, -1 }, BOOLEAN_FALSE },
|
||||
"ro.device_owner",
|
||||
{ NULL, -1, BOOLEAN_FALSE },
|
||||
{ { NULL, -1 }, BOOLEAN_FALSE },
|
||||
evaluate_security
|
||||
};
|
||||
|
||||
return do_cache2(&security);
|
||||
return do_cache2_char(&security);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface that represents the logd buffer size determination so that others
|
||||
* need not guess our intentions.
|
||||
*/
|
||||
|
||||
/* Property helper */
|
||||
static bool check_flag(const char* prop, const char* flag) {
|
||||
const char* cp = strcasestr(prop, flag);
|
||||
if (!cp) {
|
||||
return false;
|
||||
}
|
||||
/* We only will document comma (,) */
|
||||
static const char sep[] = ",:;|+ \t\f";
|
||||
if ((cp != prop) && !strchr(sep, cp[-1])) {
|
||||
return false;
|
||||
}
|
||||
cp += strlen(flag);
|
||||
return !*cp || !!strchr(sep, *cp);
|
||||
}
|
||||
|
||||
/* cache structure */
|
||||
struct cache_property {
|
||||
struct cache cache;
|
||||
char property[PROP_VALUE_MAX];
|
||||
};
|
||||
|
||||
static void refresh_cache_property(struct cache_property* cache, const char* key)
|
||||
{
|
||||
if (!cache->cache.pinfo) {
|
||||
cache->cache.pinfo = __system_property_find(key);
|
||||
if (!cache->cache.pinfo) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
cache->cache.serial = __system_property_serial(cache->cache.pinfo);
|
||||
__system_property_read(cache->cache.pinfo, 0, cache->property);
|
||||
}
|
||||
|
||||
/* get boolean with the logger twist that supports eng adjustments */
|
||||
LIBLOG_ABI_PRIVATE bool __android_logger_property_get_bool(const char* key,
|
||||
int flag)
|
||||
{
|
||||
struct cache_property property = { { NULL, -1 }, { 0 } };
|
||||
if (flag & BOOL_DEFAULT_FLAG_PERSIST) {
|
||||
char newkey[PROP_NAME_MAX];
|
||||
snprintf(newkey, sizeof(newkey), "ro.%s", key);
|
||||
refresh_cache_property(&property, newkey);
|
||||
property.cache.pinfo = NULL;
|
||||
property.cache.serial = -1;
|
||||
snprintf(newkey, sizeof(newkey), "persist.%s", key);
|
||||
refresh_cache_property(&property, newkey);
|
||||
property.cache.pinfo = NULL;
|
||||
property.cache.serial = -1;
|
||||
}
|
||||
|
||||
refresh_cache_property(&property, key);
|
||||
|
||||
if (check_flag(property.property, "true")) {
|
||||
return true;
|
||||
}
|
||||
if (check_flag(property.property, "false")) {
|
||||
return false;
|
||||
}
|
||||
if (check_flag(property.property, "eng")) {
|
||||
flag |= BOOL_DEFAULT_FLAG_ENG;
|
||||
}
|
||||
/* this is really a "not" flag */
|
||||
if (check_flag(property.property, "svelte")) {
|
||||
flag |= BOOL_DEFAULT_FLAG_SVELTE;
|
||||
}
|
||||
|
||||
/* Sanity Check */
|
||||
if (flag & (BOOL_DEFAULT_FLAG_SVELTE | BOOL_DEFAULT_FLAG_ENG)) {
|
||||
flag &= ~BOOL_DEFAULT_FLAG_TRUE_FALSE;
|
||||
flag |= BOOL_DEFAULT_TRUE;
|
||||
}
|
||||
|
||||
if ((flag & BOOL_DEFAULT_FLAG_SVELTE)
|
||||
&& __android_logger_property_get_bool("ro.config.low_ram",
|
||||
BOOL_DEFAULT_FALSE)) {
|
||||
return false;
|
||||
}
|
||||
if ((flag & BOOL_DEFAULT_FLAG_ENG) && !__android_log_is_debuggable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (flag & BOOL_DEFAULT_FLAG_TRUE_FALSE) != BOOL_DEFAULT_FALSE;
|
||||
}
|
||||
|
||||
LIBLOG_ABI_PRIVATE bool __android_logger_valid_buffer_size(unsigned long value)
|
||||
{
|
||||
static long pages, pagesize;
|
||||
unsigned long maximum;
|
||||
|
||||
if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pages) {
|
||||
pages = sysconf(_SC_PHYS_PAGES);
|
||||
}
|
||||
if (pages < 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!pagesize) {
|
||||
pagesize = sysconf(_SC_PAGESIZE);
|
||||
if (pagesize <= 1) {
|
||||
pagesize = PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/* maximum memory impact a somewhat arbitrary ~3% */
|
||||
pages = (pages + 31) / 32;
|
||||
maximum = pages * pagesize;
|
||||
|
||||
if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return value <= maximum;
|
||||
}
|
||||
|
||||
struct cache2_property_size {
|
||||
pthread_mutex_t lock;
|
||||
uint32_t serial;
|
||||
const char* key_persist;
|
||||
struct cache_property cache_persist;
|
||||
const char* key_ro;
|
||||
struct cache_property cache_ro;
|
||||
unsigned long (*const evaluate)(const struct cache2_property_size* self);
|
||||
};
|
||||
|
||||
static inline unsigned long do_cache2_property_size(struct cache2_property_size* self)
|
||||
{
|
||||
uint32_t current_serial;
|
||||
int change_detected;
|
||||
unsigned long v;
|
||||
|
||||
if (pthread_mutex_trylock(&self->lock)) {
|
||||
/* We are willing to accept some race in this context */
|
||||
return self->evaluate(self);
|
||||
}
|
||||
|
||||
change_detected = check_cache(&self->cache_persist.cache)
|
||||
|| check_cache(&self->cache_ro.cache);
|
||||
current_serial = __system_property_area_serial();
|
||||
if (current_serial != self->serial) {
|
||||
change_detected = 1;
|
||||
}
|
||||
if (change_detected) {
|
||||
refresh_cache_property(&self->cache_persist, self->key_persist);
|
||||
refresh_cache_property(&self->cache_ro, self->key_ro);
|
||||
self->serial = current_serial;
|
||||
}
|
||||
v = self->evaluate(self);
|
||||
|
||||
pthread_mutex_unlock(&self->lock);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static unsigned long property_get_size_from_cache(const struct cache_property* cache)
|
||||
{
|
||||
char* cp;
|
||||
unsigned long value = strtoul(cache->property, &cp, 10);
|
||||
|
||||
switch(*cp) {
|
||||
case 'm':
|
||||
case 'M':
|
||||
value *= 1024;
|
||||
/* FALLTHRU */
|
||||
case 'k':
|
||||
case 'K':
|
||||
value *= 1024;
|
||||
/* FALLTHRU */
|
||||
case '\0':
|
||||
break;
|
||||
|
||||
default:
|
||||
value = 0;
|
||||
}
|
||||
|
||||
if (!__android_logger_valid_buffer_size(value)) {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static unsigned long evaluate_property_get_size(const struct cache2_property_size* self)
|
||||
{
|
||||
unsigned long size = property_get_size_from_cache(&self->cache_persist);
|
||||
if (size) {
|
||||
return size;
|
||||
}
|
||||
return property_get_size_from_cache(&self->cache_ro);
|
||||
}
|
||||
|
||||
LIBLOG_ABI_PRIVATE unsigned long __android_logger_get_buffer_size(log_id_t logId)
|
||||
{
|
||||
static const char global_tunable[] = "persist.logd.size"; /* Settings App */
|
||||
static const char global_default[] = "ro.logd.size"; /* BoardConfig.mk */
|
||||
static struct cache2_property_size global = {
|
||||
PTHREAD_MUTEX_INITIALIZER,
|
||||
0,
|
||||
global_tunable,
|
||||
{ { NULL, -1 }, {} },
|
||||
global_default,
|
||||
{ { NULL, -1 }, {} },
|
||||
evaluate_property_get_size
|
||||
};
|
||||
char key_persist[PROP_NAME_MAX];
|
||||
char key_ro[PROP_NAME_MAX];
|
||||
struct cache2_property_size local = {
|
||||
PTHREAD_MUTEX_INITIALIZER,
|
||||
0,
|
||||
key_persist,
|
||||
{ { NULL, -1 }, {} },
|
||||
key_ro,
|
||||
{ { NULL, -1 }, {} },
|
||||
evaluate_property_get_size
|
||||
};
|
||||
unsigned long property_size, default_size;
|
||||
|
||||
default_size = do_cache2_property_size(&global);
|
||||
if (!default_size) {
|
||||
default_size = __android_logger_property_get_bool("ro.config.low_ram",
|
||||
BOOL_DEFAULT_FALSE)
|
||||
? LOG_BUFFER_MIN_SIZE /* 64K */
|
||||
: LOG_BUFFER_SIZE; /* 256K */
|
||||
}
|
||||
|
||||
snprintf(key_persist, sizeof(key_persist), "%s.%s",
|
||||
global_tunable, android_log_id_to_name(logId));
|
||||
snprintf(key_ro, sizeof(key_ro), "%s.%s",
|
||||
global_default, android_log_id_to_name(logId));
|
||||
property_size = do_cache2_property_size(&local);
|
||||
|
||||
if (!property_size) {
|
||||
property_size = default_size;
|
||||
}
|
||||
|
||||
if (!property_size) {
|
||||
property_size = LOG_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
return property_size;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue