// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary // source code may only be used and distributed under the Widevine License // Agreement. // // Log - implemented using the standard Android logging mechanism /* * Qutoing from system/core/include/log/log.h: * Normally we strip ALOGV (VERBOSE messages) from release builds. * You can modify this (for example with "#define LOG_NDEBUG 0" * at the top of your source file) to change that behavior. */ #ifndef LOG_NDEBUG # ifdef NDEBUG # define LOG_NDEBUG 1 # else # define LOG_NDEBUG 0 # endif #endif #define LOG_TAG "WVCdm" #define LOG_BUF_SIZE 5120 #include "log.h" #include #include #include #include #include #include #include /* * Uncomment the line below if you want to have the LOGV messages to print * IMPORTANT : this will affect all of CDM */ // #define LOG_NDEBUG 0 namespace wvutil { namespace { int64_t GetCurrentTimeMs() { struct timeval tv {}; gettimeofday(&tv, NULL); auto msec1 = static_cast(tv.tv_sec) * 1000; auto msec2 = static_cast(tv.tv_usec) / 1000; return msec1 + msec2; } } // namespace LogPriority g_cutoff = LOG_VERBOSE; LogBuffer g_logbuf; thread_local bool tl_logging_uid_set_ = false; thread_local uint32_t tl_logging_uid_ = UNKNOWN_UID; void SetLoggingUid(const uint32_t uid) { tl_logging_uid_set_ = true; tl_logging_uid_ = uid; } void ClearLoggingUid() { tl_logging_uid_set_ = false; tl_logging_uid_ = UNKNOWN_UID; } uint32_t GetLoggingUid() { return tl_logging_uid_; } uint32_t GetIpcCallingUid() { const auto self = android::hardware::IPCThreadState::selfOrNull(); return self ? self->getCallingUid() : UNKNOWN_UID; } void InitLogging() {} void Log(const char* file, const char* function, int line, LogPriority level, const char* format, ...) { const char* filename = strrchr(file, '/'); filename = filename == nullptr ? file : filename + 1; static thread_local char buf[LOG_BUF_SIZE]; int len = snprintf(buf, LOG_BUF_SIZE, "[%s(%d):%s] ", filename, line, function); if (len < 0) len = 0; if (static_cast(len) < sizeof(buf)) { va_list ap; va_start(ap, format); vsnprintf(buf + len, LOG_BUF_SIZE - len, format, ap); va_end(ap); } android_LogPriority prio = ANDROID_LOG_VERBOSE; switch (level) { case LOG_SILENT: return; // It is nonsensical to pass LOG_SILENT. case LOG_ERROR: prio = ANDROID_LOG_ERROR; break; case LOG_WARN: prio = ANDROID_LOG_WARN; break; case LOG_INFO: prio = ANDROID_LOG_INFO; break; case LOG_DEBUG: prio = ANDROID_LOG_DEBUG; break; #if LOG_NDEBUG case LOG_VERBOSE: return; #else case LOG_VERBOSE: prio = ANDROID_LOG_VERBOSE; break; #endif } __android_log_write(prio, LOG_TAG, buf); if (level <= LOG_INFO) { uint32_t uid = tl_logging_uid_set_ ? tl_logging_uid_ : GetIpcCallingUid(); g_logbuf.addLog({uid, GetCurrentTimeMs(), level, buf}); } } void LogBuffer::addLog(const LogMessage& log) { std::unique_lock lock(mutex_); buffer_.push_back(log); while (buffer_.size() > MAX_CAPACITY) { buffer_.pop_front(); } } std::vector LogBuffer::getLogs() { std::unique_lock lock(mutex_); return {buffer_.begin(), buffer_.end()}; } } // namespace wvutil