diff --git a/include/log/log.h b/include/log/log.h index 7f952ffc4..81885ce65 100644 --- a/include/log/log.h +++ b/include/log/log.h @@ -531,6 +531,12 @@ typedef enum { #define android_btWriteLog(tag, type, payload, len) \ __android_log_btwrite(tag, type, payload, len) +#define android_errorWriteLog(tag, subTag) \ + __android_log_error_write(tag, subTag, -1, NULL, 0) + +#define android_errorWriteWithInfoLog(tag, subTag, uid, data, dataLen) \ + __android_log_error_write(tag, subTag, uid, data, dataLen) + // TODO: remove these prototypes and their users #define android_testLog(prio, tag) (1) #define android_writevLog(vec,num) do{}while(0) @@ -553,6 +559,9 @@ typedef enum log_id { #define sizeof_log_id_t sizeof(typeof_log_id_t) #define typeof_log_id_t unsigned char +int __android_log_error_write(int tag, const char *subTag, int32_t uid, const char *data, + uint32_t dataLen); + /* * Send a simple string to the log. */ diff --git a/liblog/Android.mk b/liblog/Android.mk index 0d6c970bf..49efd07f5 100644 --- a/liblog/Android.mk +++ b/liblog/Android.mk @@ -16,7 +16,7 @@ LOCAL_PATH := $(my-dir) include $(CLEAR_VARS) -liblog_sources := logd_write.c +liblog_sources := logd_write.c log_event_write.c # some files must not be compiled when building against Mingw # they correspond to features not used by our host development tools diff --git a/liblog/log_event_write.c b/liblog/log_event_write.c new file mode 100644 index 000000000..0bc42d548 --- /dev/null +++ b/liblog/log_event_write.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015 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. + */ + +#include +#include + +#include +#include + +#define MAX_EVENT_PAYLOAD 512 +#define MAX_SUBTAG_LEN 32 + +static inline void copy4LE(uint8_t *buf, size_t pos, int val) +{ + buf[pos] = val & 0xFF; + buf[pos+1] = (val >> 8) & 0xFF; + buf[pos+2] = (val >> 16) & 0xFF; + buf[pos+3] = (val >> 24) & 0xFF; +} + +int __android_log_error_write(int tag, const char *subTag, int32_t uid, const char *data, + uint32_t dataLen) +{ + uint8_t buf[MAX_EVENT_PAYLOAD]; + size_t pos = 0; + uint32_t subTagLen = 0; + uint32_t roomLeftForData = 0; + + if ((subTag == NULL) || ((data == NULL) && (dataLen != 0))) return -EINVAL; + + subTagLen = strlen(subTag); + + // Truncate subtags that are too long. + subTagLen = subTagLen > MAX_SUBTAG_LEN ? MAX_SUBTAG_LEN : subTagLen; + + // Truncate dataLen if it is too long. + roomLeftForData = MAX_EVENT_PAYLOAD - + (1 + // EVENT_TYPE_LIST + 1 + // Number of elements in list + 1 + // EVENT_TYPE_STRING + sizeof(subTagLen) + + subTagLen + + 1 + // EVENT_TYPE_INT + sizeof(uid) + + 1 + // EVENT_TYPE_STRING + sizeof(dataLen)); + dataLen = dataLen > roomLeftForData ? roomLeftForData : dataLen; + + buf[pos++] = EVENT_TYPE_LIST; + buf[pos++] = 3; // Number of elements in the list (subTag, uid, data) + + // Write sub tag. + buf[pos++] = EVENT_TYPE_STRING; + copy4LE(buf, pos, subTagLen); + pos += 4; + memcpy(&buf[pos], subTag, subTagLen); + pos += subTagLen; + + // Write UID. + buf[pos++] = EVENT_TYPE_INT; + copy4LE(buf, pos, uid); + pos += 4; + + // Write data. + buf[pos++] = EVENT_TYPE_STRING; + copy4LE(buf, pos, dataLen); + pos += 4; + if (dataLen != 0) + { + memcpy(&buf[pos], data, dataLen); + pos += dataLen; + } + + return __android_log_bwrite(tag, buf, pos); +}