288 lines
6.9 KiB
C++
288 lines
6.9 KiB
C++
/*
|
|
* Copyright (C) 2024 Amlogic Corporation.
|
|
*
|
|
* 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 <iostream>
|
|
#include <unistd.h>
|
|
#include <cstdio>
|
|
#include <cstdarg>
|
|
#include <cstring>
|
|
#include <fcntl.h>
|
|
#include <sys/time.h>
|
|
#include <cstdint>
|
|
#include <sstream>
|
|
#include <unordered_map>
|
|
|
|
#ifdef DISPLAY_LOGLIB
|
|
#include <cutils/log.h>
|
|
#endif
|
|
|
|
#include "DispAdptLog.h"
|
|
#include "MesonTypes.h"
|
|
|
|
static int g_activeLevel = DEFAULT_LOG_LEVEL;
|
|
FILE *g_file = NULL;
|
|
FILE *g_close_file = NULL;
|
|
static int g_di_number = -1;
|
|
static int g_di_log = -1;
|
|
static bool g_alog = false;
|
|
|
|
FILE *getDebugFile()
|
|
{
|
|
if (!g_file) {
|
|
if (!g_close_file)
|
|
return stderr;
|
|
return g_close_file;
|
|
}
|
|
return g_file;
|
|
}
|
|
|
|
long long DispAdptGetCurrentTime(void)
|
|
{
|
|
long long utcCurrentTimeMillis;
|
|
timespec ts;
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
utcCurrentTimeMillis = ts.tv_sec * 1000LL + ts.tv_nsec / 1000000LL;
|
|
|
|
return utcCurrentTimeMillis;
|
|
}
|
|
|
|
long long DispAdptGetCurrentTimeUs(void)
|
|
{
|
|
long long utcCurrentTimeUs;
|
|
timespec ts;
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
utcCurrentTimeUs = ts.tv_sec * 1000000LL + ts.tv_nsec / 1000LL;
|
|
|
|
return utcCurrentTimeUs;
|
|
}
|
|
|
|
#ifdef DISPLAY_LOGLIB
|
|
void DispAdptLog(int level, const char *fmt, ...)
|
|
{
|
|
if (level <= g_activeLevel) {
|
|
va_list argptr;
|
|
va_start(argptr, fmt);
|
|
|
|
if (g_alog) {
|
|
DispAdptLogPrint(ANDROID_LOG_INFO, DISPLAY_TAG, fmt, argptr);
|
|
} else {
|
|
fprintf(getDebugFile(), "%lld: pid: %d ", DispAdptGetCurrentTime(), getpid());
|
|
vfprintf(getDebugFile(), fmt, argptr);
|
|
fflush(getDebugFile());
|
|
}
|
|
va_end(argptr);
|
|
}
|
|
}
|
|
#else
|
|
void DispAdptLog(int level, const char *fmt, ...)
|
|
{
|
|
if (level <= g_activeLevel) {
|
|
va_list argptr;
|
|
fprintf(getDebugFile(), "%lld: pid: %d ", DispAdptGetCurrentTime(), getpid());
|
|
va_start(argptr, fmt);
|
|
vfprintf(getDebugFile(), fmt, argptr);
|
|
fflush(getDebugFile());
|
|
va_end(argptr);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void reset()
|
|
{
|
|
g_activeLevel = DEFAULT_LOG_LEVEL;
|
|
g_di_number = -1;
|
|
g_di_log = -1;
|
|
g_alog = false;
|
|
|
|
if (g_file)
|
|
fclose(g_file);
|
|
g_file = NULL;
|
|
}
|
|
|
|
void DispAdptLogInit()
|
|
{
|
|
char buf[MESON_MAX_STR_LEN] = { 0 };
|
|
char path[MESON_MAX_STR_LEN] = { 0 };
|
|
|
|
g_close_file = fopen(CLOSE_LOG, "w");
|
|
|
|
snprintf(path, sizeof(path), "%s/%s", ADPT_LISTENER_DIR, DEBUG_LOG);
|
|
if (DispAdptReadFile(path, buf, true, MESON_MAX_STR_LEN) == 0) {
|
|
reset();
|
|
DispAdptDebugSetting(buf);
|
|
}
|
|
|
|
const char *env = getenv("DISPLAY_DEBUG_FILE");
|
|
if (env && g_file == NULL) {
|
|
if (!strcmp(env, "stdout"))
|
|
g_file = stdout;
|
|
else
|
|
g_file = fopen(env, "w");
|
|
}
|
|
|
|
if (g_activeLevel < 0)
|
|
g_activeLevel = DEFAULT_LOG_LEVEL;
|
|
env = getenv("DISPLAY_DEBUG");
|
|
if (env) {
|
|
g_activeLevel = atoi(env);
|
|
}
|
|
}
|
|
|
|
int DispAdptReadFile(const char *path, char *val, bool original, int valSize)
|
|
{
|
|
char buf[MESON_MAX_STR_LEN] = { 0 };
|
|
|
|
int fd, len;
|
|
if ((fd = open(path, O_RDONLY)) < 0) {
|
|
DISPLAY_LOGE("open %s fail. Error info [%s]", path, strerror(errno));
|
|
return -errno;
|
|
}
|
|
|
|
len = read(fd, buf, MESON_MAX_STR_LEN - 1);
|
|
close(fd);
|
|
if (len < 0) {
|
|
DISPLAY_LOGE("read error: %s, %s\n", path, strerror(errno));
|
|
return -errno;
|
|
}
|
|
|
|
if (!original) {
|
|
int i, j;
|
|
for (i = 0, j = 0; i <= len - 1; i++) {
|
|
/*
|
|
* change '\0' to 0x20(spacing), otherwise the string buffer will be cut off
|
|
* if the last char is '\0' should not replace it
|
|
*/
|
|
if (0x0 == buf[i] && i < len - 1) {
|
|
buf[i] = 0x20;
|
|
DISPLAY_LOGD("read buffer index:%d is a 0x0, replace to spacing \n", i);
|
|
}
|
|
|
|
/* delete all the character of '\n' and '\r'*/
|
|
if (0x0a != buf[i] && 0x0d != buf[i]) {
|
|
buf[j++] = buf[i];
|
|
}
|
|
}
|
|
|
|
buf[j] = 0x0;
|
|
}
|
|
|
|
DISPLAY_LOGD("read %s, result length:%d, val:%s\n", path, len, buf);
|
|
|
|
strncpy(val, buf, valSize);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int DispAdptWriteFile(const char *path, const char *val)
|
|
{
|
|
int fd;
|
|
|
|
if ((fd = open(path, O_RDWR)) < 0) {
|
|
DISPLAY_LOGE("open %s fail. Error info [%s]", path, strerror(errno));
|
|
return -errno;
|
|
}
|
|
|
|
DISPLAY_LOGD("%s: write (%s) to file (%s)", __func__, val, path);
|
|
if (write(fd, val, strlen(val)) != (int)strlen(val))
|
|
DISPLAY_LOGE("write %s failed!\n", path);
|
|
|
|
close(fd);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int DispAdptGetDiNumber()
|
|
{
|
|
return g_di_number;
|
|
}
|
|
|
|
int DispAdptGetDiLog()
|
|
{
|
|
return g_di_log;
|
|
}
|
|
|
|
std::unordered_map<std::string, std::string> parseKeyValue(const std::string& input) {
|
|
std::unordered_map<std::string, std::string> result;
|
|
std::stringstream ss(input);
|
|
std::string key, value;
|
|
std::string kvPair;
|
|
|
|
while (ss >> kvPair) {
|
|
size_t eqPos = kvPair.find('=');
|
|
if (eqPos != std::string::npos) {
|
|
key = kvPair.substr(0, eqPos);
|
|
value = kvPair.substr(eqPos + 1);
|
|
result[key] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int DispAdptDebugSetting(char *content)
|
|
{
|
|
auto parsed = parseKeyValue(content);
|
|
|
|
for (const auto& pair : parsed) {
|
|
if (pair.first == "DISPLAY_DEBUG")
|
|
g_activeLevel = atoi(pair.second.c_str());
|
|
|
|
if (pair.first == "DISPLAY_DEBUG_FILE") {
|
|
if (g_file == NULL)
|
|
g_file = fopen(pair.second.c_str(), "a");
|
|
}
|
|
|
|
if (pair.first == "DI_NUMBER")
|
|
g_di_number = atoi(pair.second.c_str());
|
|
|
|
if (pair.first == "DI_LOG")
|
|
g_di_log = atoi(pair.second.c_str());
|
|
|
|
if (pair.first == "ALOG")
|
|
g_alog = atoi(pair.second.c_str()) > 0 ? true : false;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void DispAdptLogDestroy()
|
|
{
|
|
if (g_file != NULL)
|
|
fclose(g_file);
|
|
g_file = NULL;
|
|
if (g_close_file != NULL)
|
|
fclose(g_close_file);
|
|
g_close_file = NULL;
|
|
}
|
|
|
|
#ifdef DISPLAY_LOGLIB
|
|
void DispAdptLogPrint(int prio, const char* tag, const char* fmt, va_list args)
|
|
{
|
|
char buf[1024];
|
|
int len;
|
|
|
|
len = snprintf(buf, sizeof(buf), "[%lld] ", DispAdptGetCurrentTime());
|
|
len = vsnprintf(buf + len, sizeof(buf) - len, fmt, args);
|
|
if (len >= 0 && len < (int)sizeof(buf))
|
|
__android_log_print(prio, tag, "%s", buf);
|
|
else
|
|
__android_log_print(prio, tag, "[TRUNCATED]%s", buf);
|
|
}
|
|
#endif
|
|
|