liblog: Add android_set_log_frontend am: 850d06e1c9 am: 9d68551f47

am: b6c6c7e3d3

Change-Id: I942aff87d5a45b5e18bb03c2ea2ebf7bfebd976d
This commit is contained in:
Mark Salyzyn 2017-02-09 15:38:00 +00:00 committed by android-build-merger
commit 94acd67ba8
4 changed files with 180 additions and 1 deletions

View file

@ -108,6 +108,11 @@ SYNOPSIS
int android_log_destroy(android_log_context *ctx)
#include <log/log_frontend.h>
int android_set_log_frontend(int frontend_flag)
int android_get_log_frontend()
Link with -llog
DESCRIPTION
@ -162,6 +167,12 @@ DESCRIPTION
when opening the sub-log. It is recommended to open the log
ANDROID_LOG_RDONLY in these cases.
android_set_log_frontend() selects frontend filters. Argument is either
LOGGER_DEFAULT, LOGGER_LOGD or LOGGER_NULL. The latter drops all
content on the floor. Both android_set_log_frontend() and
android_get_log_frontend() return the current frontend mask, or a
negative errno for any problems.
ERRORS
If messages fail, a negative error code will be returned to the caller.
@ -194,4 +205,4 @@ SEE ALSO
17 Oct 2016 LIBLOG(3)
08 Feb 2017 LIBLOG(3)

View file

@ -0,0 +1,33 @@
/*
**
** Copyright 2017, The Android Open Source Project
**
** This file is dual licensed. It may be redistributed and/or modified
** under the terms of the Apache 2.0 License OR version 2 of the GNU
** General Public License.
*/
#ifndef _LIBS_LOG_FRONTEND_H
#define _LIBS_LOG_FRONTEND_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Logging frontends, bit mask to select features. Function returns selection.
*/
#define LOGGER_DEFAULT 0x0
#define LOGGER_LOGD 0x1
#define LOGGER_KERNEL 0x2 /* Reserved/Deprecated */
#define LOGGER_NULL 0x4 /* Does not release resources of other selections */
/* Both return the selected frontend flag mask, or negative errno */
int android_set_log_frontend(int frontend_flag);
int android_get_log_frontend();
#ifdef __cplusplus
}
#endif
#endif /* _LIBS_LOG_FRONTEND_H */

View file

@ -25,6 +25,7 @@
#endif
#include <log/event_tag_map.h>
#include <log/log_frontend.h>
#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
@ -618,3 +619,67 @@ LIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag,
return write_to_log(LOG_ID_SECURITY, vec, 4);
}
static int __write_to_log_null(log_id_t log_id, struct iovec* vec, size_t nr)
{
size_t len, i;
if ((log_id < LOG_ID_MIN) || (log_id >= LOG_ID_MAX)) {
return -EINVAL;
}
for (len = i = 0; i < nr; ++i) {
len += vec[i].iov_len;
}
if (!len) {
return -EINVAL;
}
return len;
}
/* Following functions need access to our internal write_to_log status */
LIBLOG_ABI_PUBLIC int android_set_log_frontend(int frontend_flag)
{
if (frontend_flag < 0) {
return -EINVAL;
}
__android_log_lock();
if (frontend_flag & LOGGER_NULL) {
write_to_log = __write_to_log_null;
__android_log_unlock();
return LOGGER_NULL;
}
/* Anything else, act as if LOGGER_DEFAULT */
/* generically we only expect these two values for write_to_log */
if ((write_to_log != __write_to_log_init) &&
(write_to_log != __write_to_log_daemon)) {
write_to_log = __write_to_log_init;
}
__android_log_unlock();
return LOGGER_DEFAULT;
}
LIBLOG_ABI_PUBLIC int android_get_log_frontend()
{
int ret = LOGGER_DEFAULT;
__android_log_lock();
if (write_to_log == __write_to_log_null) {
ret = LOGGER_NULL;
} else if ((write_to_log != __write_to_log_init) &&
(write_to_log != __write_to_log_daemon)) {
ret = -EINVAL;
}
__android_log_unlock();
return ret;
}

View file

@ -37,6 +37,7 @@
#include <gtest/gtest.h>
#include <log/logprint.h>
#include <log/log_event_list.h>
#include <log/log_frontend.h>
#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
@ -225,6 +226,75 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
#endif
}
// This test makes little sense standalone, and requires the tests ahead
// and behind us, to make us whole. We could incorporate a prefix and
// suffix test to make this standalone, but opted to not complicate this.
TEST(liblog, android_set_log_frontend) {
#ifdef __ANDROID__
int logger = android_get_log_frontend();
EXPECT_NE(LOGGER_NULL, logger);
EXPECT_EQ(LOGGER_NULL, android_set_log_frontend(LOGGER_NULL));
EXPECT_EQ(LOGGER_NULL, android_get_log_frontend());
pid_t pid = getpid();
struct logger_list *logger_list;
ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
log_time ts(CLOCK_MONOTONIC);
ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
usleep(1000000);
int count = 0;
for (;;) {
log_msg log_msg;
if (android_logger_list_read(logger_list, &log_msg) <= 0) {
break;
}
ASSERT_EQ(log_msg.entry.pid, pid);
if ((log_msg.entry.len != sizeof(android_log_event_long_t))
|| (log_msg.id() != LOG_ID_EVENTS)) {
continue;
}
android_log_event_long_t* eventData;
eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg());
if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) {
continue;
}
log_time tx(reinterpret_cast<char*>(&eventData->payload.data));
if (ts == tx) {
++count;
}
}
android_logger_list_close(logger_list);
EXPECT_EQ(logger, android_set_log_frontend(logger));
EXPECT_EQ(logger, android_get_log_frontend());
// False negative if liblog.__android_log_btwrite__android_logger_list_read
// fails above, so we will likely succeed. But we will have so many
// failures elsewhere that it is probably not worthwhile for us to
// highlight yet another disappointment.
EXPECT_EQ(0, count);
// We also expect failures in the following tests if the set does not
// react in an appropriate manner internally, yet passes, so we depend
// on this test being in the middle of a series of tests performed in
// the same process.
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}
#ifdef __ANDROID__
static inline int32_t get4LE(const char* src)
{