From 472245d9625b8f0c52737aa8753524facfa211db Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Fri, 18 Nov 2016 10:45:45 -0800 Subject: [PATCH] liblog: move android_log_event_context class to log/log_event_list.h rename class from android_log_event_context to android_log_event_list Test: gTest logcat-unit-tests Bug: 31992412 Bug: 31456426 Change-Id: Ib61cbca7d453837d64959c56b0e11f8c5edbfbdd --- bootstat/histogram_logger.cpp | 4 +- include/log/log.h | 210 +----------------------- include/log/log_event_list.h | 296 ++++++++++++++++++++++++++++++++++ liblog/log_event_list.c | 1 + liblog/log_event_write.c | 1 + liblog/tests/liblog_test.cpp | 1 + logcat/tests/logcat_test.cpp | 31 ++-- 7 files changed, 318 insertions(+), 226 deletions(-) create mode 100644 include/log/log_event_list.h diff --git a/bootstat/histogram_logger.cpp b/bootstat/histogram_logger.cpp index 6a9ef2bda..73f32951f 100644 --- a/bootstat/histogram_logger.cpp +++ b/bootstat/histogram_logger.cpp @@ -19,13 +19,13 @@ #include #include -#include +#include namespace bootstat { void LogHistogram(const std::string& event, int32_t data) { LOG(INFO) << "Logging histogram: " << event << " " << data; - android_log_event_context log(HISTOGRAM_LOG_TAG); + android_log_event_list log(HISTOGRAM_LOG_TAG); log << event << data << LOG_ID_EVENTS; } diff --git a/include/log/log.h b/include/log/log.h index a44aba898..d6f0eb524 100644 --- a/include/log/log.h +++ b/include/log/log.h @@ -27,15 +27,8 @@ #include /* clock_gettime */ #include -#include /* helper to define iovec for portability */ - -#if (defined(__cplusplus) && defined(_USING_LIBCXX)) -extern "C++" { -#include -} -#endif - #include +#include /* helper to define iovec for portability */ #ifdef __cplusplus extern "C" { @@ -774,207 +767,6 @@ const char* android_log_id_to_name(log_id_t log_id); /* --------------------------------------------------------------------- */ -#ifndef __ANDROID_USE_LIBLOG_EVENT_INTERFACE -#ifndef __ANDROID_API__ -#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 1 -#elif __ANDROID_API__ > 23 /* > Marshmallow */ -#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 1 -#else -#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 0 -#endif -#endif - -#if __ANDROID_USE_LIBLOG_EVENT_INTERFACE - -/* For manipulating lists of events. */ - -#define ANDROID_MAX_LIST_NEST_DEPTH 8 - -/* - * The opaque context used to manipulate lists of events. - */ -#ifndef __android_log_context_defined -#define __android_log_context_defined -typedef struct android_log_context_internal* android_log_context; -#endif - -/* - * Elements returned when reading a list of events. - */ -#ifndef __android_log_list_element_defined -#define __android_log_list_element_defined -typedef struct { - AndroidEventLogType type; - uint16_t complete; - uint16_t len; - union { - int32_t int32; - int64_t int64; - char* string; - float float32; - } data; -} android_log_list_element; -#endif - -/* - * Creates a context associated with an event tag to write elements to - * the list of events. - */ -android_log_context create_android_logger(uint32_t tag); - -/* All lists must be braced by a begin and end call */ -/* - * NB: If the first level braces are missing when specifying multiple - * elements, we will manufacturer a list to embrace it for your API - * convenience. For a single element, it will remain solitary. - */ -int android_log_write_list_begin(android_log_context ctx); -int android_log_write_list_end(android_log_context ctx); - -int android_log_write_int32(android_log_context ctx, int32_t value); -int android_log_write_int64(android_log_context ctx, int64_t value); -int android_log_write_string8(android_log_context ctx, const char* value); -int android_log_write_string8_len(android_log_context ctx, - const char* value, size_t maxlen); -int android_log_write_float32(android_log_context ctx, float value); - -/* Submit the composed list context to the specified logger id */ -/* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */ -int android_log_write_list(android_log_context ctx, log_id_t id); - -/* - * Creates a context from a raw buffer representing a list of events to be read. - */ -android_log_context create_android_log_parser(const char* msg, size_t len); - -android_log_list_element android_log_read_next(android_log_context ctx); -android_log_list_element android_log_peek_next(android_log_context ctx); - -/* Finished with reader or writer context */ -int android_log_destroy(android_log_context* ctx); - -#ifdef __cplusplus -#ifndef __class_android_log_event_context -#define __class_android_log_event_context -/* android_log_context C++ helpers */ -extern "C++" { -class android_log_event_context { - android_log_context ctx; - int ret; - - android_log_event_context(const android_log_event_context&) = delete; - void operator =(const android_log_event_context&) = delete; - -public: - explicit android_log_event_context(int tag) : ret(0) { - ctx = create_android_logger(static_cast(tag)); - } - explicit android_log_event_context(log_msg& log_msg) : ret(0) { - ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t), - log_msg.entry.len - sizeof(uint32_t)); - } - ~android_log_event_context() { android_log_destroy(&ctx); } - - int close() { - int retval = android_log_destroy(&ctx); - if (retval < 0) ret = retval; - return retval; - } - - /* To allow above C calls to use this class as parameter */ - operator android_log_context() const { return ctx; } - - int status() const { return ret; } - - int begin() { - int retval = android_log_write_list_begin(ctx); - if (retval < 0) ret = retval; - return ret; - } - int end() { - int retval = android_log_write_list_end(ctx); - if (retval < 0) ret = retval; - return ret; - } - - android_log_event_context& operator <<(int32_t value) { - int retval = android_log_write_int32(ctx, value); - if (retval < 0) ret = retval; - return *this; - } - android_log_event_context& operator <<(uint32_t value) { - int retval = android_log_write_int32(ctx, static_cast(value)); - if (retval < 0) ret = retval; - return *this; - } - android_log_event_context& operator <<(int64_t value) { - int retval = android_log_write_int64(ctx, value); - if (retval < 0) ret = retval; - return *this; - } - android_log_event_context& operator <<(uint64_t value) { - int retval = android_log_write_int64(ctx, static_cast(value)); - if (retval < 0) ret = retval; - return *this; - } - android_log_event_context& operator <<(const char* value) { - int retval = android_log_write_string8(ctx, value); - if (retval < 0) ret = retval; - return *this; - } -#if defined(_USING_LIBCXX) - android_log_event_context& operator <<(const std::string& value) { - int retval = android_log_write_string8_len(ctx, - value.data(), - value.length()); - if (retval < 0) ret = retval; - return *this; - } -#endif - android_log_event_context& operator <<(float value) { - int retval = android_log_write_float32(ctx, value); - if (retval < 0) ret = retval; - return *this; - } - - int write(log_id_t id = LOG_ID_EVENTS) { - int retval = android_log_write_list(ctx, id); - if (retval < 0) ret = retval; - return ret; - } - - int operator <<(log_id_t id) { - int retval = android_log_write_list(ctx, id); - if (retval < 0) ret = retval; - android_log_destroy(&ctx); - return ret; - } - - /* - * Append should be a lesser-used interface, but adds - * access to string with length. So we offer all types. - */ - template - bool Append(Tvalue value) { *this << value; return ret >= 0; } - - bool Append(const char* value, size_t len) { - int retval = android_log_write_string8_len(ctx, value, len); - if (retval < 0) ret = retval; - return ret >= 0; - } - - android_log_list_element read() { return android_log_read_next(ctx); } - android_log_list_element peek() { return android_log_peek_next(ctx); } - -}; -} -#endif -#endif - -#endif /* __ANDROID_USE_LIBLOG_EVENT_INTERFACE */ - -/* --------------------------------------------------------------------- */ - #ifndef _ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE #ifndef __ANDROID_API__ #define __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE 1 diff --git a/include/log/log_event_list.h b/include/log/log_event_list.h new file mode 100644 index 000000000..04c1cd6fb --- /dev/null +++ b/include/log/log_event_list.h @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2005-2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_LOG_EVENT_LIST_H +#define _LIBS_LOG_EVENT_LIST_H + +#include + +#if (defined(__cplusplus) && defined(_USING_LIBCXX)) +extern "C++" { +#include +} +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __ANDROID_USE_LIBLOG_EVENT_INTERFACE +#ifndef __ANDROID_API__ +#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 1 +#elif __ANDROID_API__ > 23 /* > Marshmallow */ +#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 1 +#else +#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 0 +#endif +#endif + +#if __ANDROID_USE_LIBLOG_EVENT_INTERFACE + +/* For manipulating lists of events. */ + +#define ANDROID_MAX_LIST_NEST_DEPTH 8 + +/* + * The opaque context used to manipulate lists of events. + */ +#ifndef __android_log_context_defined +#define __android_log_context_defined +typedef struct android_log_context_internal* android_log_context; +#endif + +/* + * Elements returned when reading a list of events. + */ +#ifndef __android_log_list_element_defined +#define __android_log_list_element_defined +typedef struct { + AndroidEventLogType type; + uint16_t complete; + uint16_t len; + union { + int32_t int32; + int64_t int64; + char* string; + float float32; + } data; +} android_log_list_element; +#endif + +/* + * Creates a context associated with an event tag to write elements to + * the list of events. + */ +android_log_context create_android_logger(uint32_t tag); + +/* All lists must be braced by a begin and end call */ +/* + * NB: If the first level braces are missing when specifying multiple + * elements, we will manufacturer a list to embrace it for your API + * convenience. For a single element, it will remain solitary. + */ +int android_log_write_list_begin(android_log_context ctx); +int android_log_write_list_end(android_log_context ctx); + +int android_log_write_int32(android_log_context ctx, int32_t value); +int android_log_write_int64(android_log_context ctx, int64_t value); +int android_log_write_string8(android_log_context ctx, const char* value); +int android_log_write_string8_len(android_log_context ctx, + const char* value, size_t maxlen); +int android_log_write_float32(android_log_context ctx, float value); + +/* Submit the composed list context to the specified logger id */ +/* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */ +int android_log_write_list(android_log_context ctx, log_id_t id); + +/* + * Creates a context from a raw buffer representing a list of events to be read. + */ +android_log_context create_android_log_parser(const char* msg, size_t len); + +android_log_list_element android_log_read_next(android_log_context ctx); +android_log_list_element android_log_peek_next(android_log_context ctx); + +/* Finished with reader or writer context */ +int android_log_destroy(android_log_context* ctx); + +#ifdef __cplusplus +#ifndef __class_android_log_event_list_defined +#define __class_android_log_event_list_defined +/* android_log_list C++ helpers */ +extern "C++" { +class android_log_event_list { + +private: + android_log_context ctx; + int ret; + + android_log_event_list(const android_log_event_list&) = delete; + void operator =(const android_log_event_list&) = delete; + +public: + explicit android_log_event_list(int tag) : ret(0) { + ctx = create_android_logger(static_cast(tag)); + } + explicit android_log_event_list(log_msg& log_msg) : ret(0) { + ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t), + log_msg.entry.len - sizeof(uint32_t)); + } + ~android_log_event_list() { android_log_destroy(&ctx); } + + int close() { + int retval = android_log_destroy(&ctx); + if (retval < 0) ret = retval; + return retval; + } + + /* To allow above C calls to use this class as parameter */ + operator android_log_context() const { return ctx; } + + int status() const { return ret; } + + int begin() { + int retval = android_log_write_list_begin(ctx); + if (retval < 0) ret = retval; + return ret; + } + int end() { + int retval = android_log_write_list_end(ctx); + if (retval < 0) ret = retval; + return ret; + } + + android_log_event_list& operator <<(int32_t value) { + int retval = android_log_write_int32(ctx, value); + if (retval < 0) ret = retval; + return *this; + } + + android_log_event_list& operator <<(uint32_t value) { + int retval = android_log_write_int32(ctx, static_cast(value)); + if (retval < 0) ret = retval; + return *this; + } + + android_log_event_list& operator <<(int64_t value) { + int retval = android_log_write_int64(ctx, value); + if (retval < 0) ret = retval; + return *this; + } + + android_log_event_list& operator <<(uint64_t value) { + int retval = android_log_write_int64(ctx, static_cast(value)); + if (retval < 0) ret = retval; + return *this; + } + + android_log_event_list& operator <<(const char* value) { + int retval = android_log_write_string8(ctx, value); + if (retval < 0) ret = retval; + return *this; + } + +#if defined(_USING_LIBCXX) + android_log_event_list& operator <<(const std::string& value) { + int retval = android_log_write_string8_len(ctx, + value.data(), + value.length()); + if (retval < 0) ret = retval; + return *this; + } +#endif + + android_log_event_list& operator <<(float value) { + int retval = android_log_write_float32(ctx, value); + if (retval < 0) ret = retval; + return *this; + } + + int write(log_id_t id = LOG_ID_EVENTS) { + int retval = android_log_write_list(ctx, id); + if (retval < 0) ret = retval; + return ret; + } + + int operator <<(log_id_t id) { + int retval = android_log_write_list(ctx, id); + if (retval < 0) ret = retval; + android_log_destroy(&ctx); + return ret; + } + + /* + * Append methods removes any integer promotion + * confusion, and adds access to string with length. + * Append methods are also added for all types for + * convenience. + */ + + bool AppendInt(int32_t value) { + int retval = android_log_write_int32(ctx, value); + if (retval < 0) ret = retval; + return ret >= 0; + } + + bool AppendLong(int64_t value) { + int retval = android_log_write_int64(ctx, value); + if (retval < 0) ret = retval; + return ret >= 0; + } + + bool AppendString(const char* value) { + int retval = android_log_write_string8(ctx, value); + if (retval < 0) ret = retval; + return ret >= 0; + } + + bool AppendString(const char* value, size_t len) { + int retval = android_log_write_string8_len(ctx, value, len); + if (retval < 0) ret = retval; + return ret >= 0; + } + +#if defined(_USING_LIBCXX) + bool AppendString(const std::string& value) { + int retval = android_log_write_string8_len(ctx, + value.data(), + value.length()); + if (retval < 0) ret = retval; + return ret; + } + + bool Append(const std::string& value) { + int retval = android_log_write_string8_len(ctx, + value.data(), + value.length()); + if (retval < 0) ret = retval; + return ret; + } +#endif + + bool AppendFloat(float value) { + int retval = android_log_write_float32(ctx, value); + if (retval < 0) ret = retval; + return ret >= 0; + } + + template + bool Append(Tvalue value) { *this << value; return ret >= 0; } + + bool Append(const char* value, size_t len) { + int retval = android_log_write_string8_len(ctx, value, len); + if (retval < 0) ret = retval; + return ret >= 0; + } + + android_log_list_element read() { return android_log_read_next(ctx); } + android_log_list_element peek() { return android_log_peek_next(ctx); } + +}; +} +#endif +#endif + +#endif /* __ANDROID_USE_LIBLOG_EVENT_INTERFACE */ + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBS_LOG_EVENT_LIST_H */ diff --git a/liblog/log_event_list.c b/liblog/log_event_list.c index 11d8afb88..8303b6339 100644 --- a/liblog/log_event_list.c +++ b/liblog/log_event_list.c @@ -22,6 +22,7 @@ #include #include +#include #include #include "log_portability.h" diff --git a/liblog/log_event_write.c b/liblog/log_event_write.c index 7262fc584..14d648273 100644 --- a/liblog/log_event_write.c +++ b/liblog/log_event_write.c @@ -18,6 +18,7 @@ #include #include +#include #include "log_portability.h" diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp index 70c7a48e7..9c418c1d6 100644 --- a/liblog/tests/liblog_test.cpp +++ b/liblog/tests/liblog_test.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp index 8d7c04eb9..11cffe64b 100644 --- a/logcat/tests/logcat_test.cpp +++ b/logcat/tests/logcat_test.cpp @@ -29,6 +29,7 @@ #include #include +#include #define BIG_BUFFER (5 * 1024) @@ -1091,7 +1092,7 @@ static bool get_white_black(char **list) { while (fgets(buffer, sizeof(buffer), fp)) { char *hold = *list; char *buf = buffer; - while (isspace(*buf)) { + while (isspace(*buf)) { ++buf; } char *end = buf + strlen(buf); @@ -1126,7 +1127,7 @@ static bool set_white_black(const char *list) { while (fgets(buffer, sizeof(buffer), fp)) { char *buf = buffer; - while (isspace(*buf)) { + while (isspace(*buf)) { ++buf; } char *end = buf + strlen(buf); @@ -1295,7 +1296,7 @@ TEST(logcat, descriptive) { { static const struct tag hhgtg = { 42, "answer" }; - android_log_event_context ctx(hhgtg.tagNo); + android_log_event_list ctx(hhgtg.tagNo); static const char theAnswer[] = "what is five by seven"; ctx << theAnswer; ctx.write(); @@ -1307,7 +1308,7 @@ TEST(logcat, descriptive) { static const struct tag sync = { 2720, "sync" }; static const char id[] = "logcat.decriptive"; { - android_log_event_context ctx(sync.tagNo); + android_log_event_list ctx(sync.tagNo); ctx << id << (int32_t)42 << (int32_t)-1 << (int32_t)0; ctx.write(); EXPECT_TRUE(End_to_End(sync.tagStr, @@ -1317,7 +1318,7 @@ TEST(logcat, descriptive) { // Partial match to description { - android_log_event_context ctx(sync.tagNo); + android_log_event_list ctx(sync.tagNo); ctx << id << (int32_t)43 << (int64_t)-1 << (int32_t)0; ctx.write(); EXPECT_TRUE(End_to_End(sync.tagStr, @@ -1327,7 +1328,7 @@ TEST(logcat, descriptive) { // Negative Test of End_to_End, ensure it is working { - android_log_event_context ctx(sync.tagNo); + android_log_event_list ctx(sync.tagNo); ctx << id << (int32_t)44 << (int32_t)-1 << (int64_t)0; ctx.write(); fprintf(stderr, "Expect a \"Closest match\" message\n"); @@ -1340,7 +1341,7 @@ TEST(logcat, descriptive) { { static const struct tag sync = { 2747, "contacts_aggregation" }; { - android_log_event_context ctx(sync.tagNo); + android_log_event_list ctx(sync.tagNo); ctx << (uint64_t)30 << (int32_t)2; ctx.write(); EXPECT_TRUE(End_to_End(sync.tagStr, @@ -1348,7 +1349,7 @@ TEST(logcat, descriptive) { } { - android_log_event_context ctx(sync.tagNo); + android_log_event_list ctx(sync.tagNo); ctx << (uint64_t)31570 << (int32_t)911; ctx.write(); EXPECT_TRUE(End_to_End(sync.tagStr, @@ -1359,42 +1360,42 @@ TEST(logcat, descriptive) { { static const struct tag sync = { 75000, "sqlite_mem_alarm_current" }; { - android_log_event_context ctx(sync.tagNo); + android_log_event_list ctx(sync.tagNo); ctx << (uint32_t)512; ctx.write(); EXPECT_TRUE(End_to_End(sync.tagStr, "current=512B")); } { - android_log_event_context ctx(sync.tagNo); + android_log_event_list ctx(sync.tagNo); ctx << (uint32_t)3072; ctx.write(); EXPECT_TRUE(End_to_End(sync.tagStr, "current=3KB")); } { - android_log_event_context ctx(sync.tagNo); + android_log_event_list ctx(sync.tagNo); ctx << (uint32_t)2097152; ctx.write(); EXPECT_TRUE(End_to_End(sync.tagStr, "current=2MB")); } { - android_log_event_context ctx(sync.tagNo); + android_log_event_list ctx(sync.tagNo); ctx << (uint32_t)2097153; ctx.write(); EXPECT_TRUE(End_to_End(sync.tagStr, "current=2097153B")); } { - android_log_event_context ctx(sync.tagNo); + android_log_event_list ctx(sync.tagNo); ctx << (uint32_t)1073741824; ctx.write(); EXPECT_TRUE(End_to_End(sync.tagStr, "current=1GB")); } { - android_log_event_context ctx(sync.tagNo); + android_log_event_list ctx(sync.tagNo); ctx << (uint32_t)3221225472; // 3MB, but on purpose overflowed ctx.write(); EXPECT_TRUE(End_to_End(sync.tagStr, "current=-1GB")); @@ -1403,7 +1404,7 @@ TEST(logcat, descriptive) { { static const struct tag sync = { 27501, "notification_panel_hidden" }; - android_log_event_context ctx(sync.tagNo); + android_log_event_list ctx(sync.tagNo); ctx.write(); EXPECT_TRUE(End_to_End(sync.tagStr, "")); }