17a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Copyright 2014 The Android Open Source Project 27a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 37a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// This software is licensed under the terms of the GNU General Public 47a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// License version 2, as published by the Free Software Foundation, and 57a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// may be copied, distributed, and modified under those terms. 67a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 77a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// This program is distributed in the hope that it will be useful, 87a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// but WITHOUT ANY WARRANTY; without even the implied warranty of 97a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 107a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// GNU General Public License for more details. 117a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 127a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#ifndef ANDROID_BASE_LOG_H 137a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define ANDROID_BASE_LOG_H 147a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 157a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#include <errno.h> 167a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#include <stdarg.h> 177a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#include <stddef.h> 187a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 197a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnernamespace android { 207a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnernamespace base { 217a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 227a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// The list of severity levels used for logging. 237a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Note that negative verbosity levels are used. 247a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnertypedef int LogSeverity; 257a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerconst LogSeverity LOG_VERBOSE = -1; 267a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerconst LogSeverity LOG_INFO = 0; 277a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerconst LogSeverity LOG_WARNING = 1; 287a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerconst LogSeverity LOG_ERROR = 2; 297a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerconst LogSeverity LOG_FATAL = 3; 307a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerconst LogSeverity LOG_NUM_SEVERITIES = 4; 317a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 327a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// LOG_DFATAL will be LOG_ERROR in release builds, and LOG_FATAL in debug 337a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// ones. 347a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#ifdef NDEBUG 357a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerconst LogSeverity LOG_DFATAL = LOG_ERROR; 367a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#else 377a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerconst LogSeverity LOG_DFATAL = LOG_FATAL; 387a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#endif 397a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 407a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Returns the minimal log level. 417a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' TurnerLogSeverity getMinLogLevel(); 427a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 437a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Helper macro used to test if logging for a given log level is 447a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// currently enabled. |severity| must be a log level without the LOG_ 457a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// prefix, as in: 467a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 477a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// if (LOG_IS_ON(INFO)) { 487a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// ... do additionnal logging 497a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// } 507a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 517a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define LOG_IS_ON(severity) \ 527a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner ((::android::base::LOG_ ## severity) >= \ 537a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner ::android::base::getMinLogLevel()) 547a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 557a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// For performance reasons, it's important to avoid constructing a 567a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// LogMessage instance every time a LOG() or CHECK() statement is 577a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// encountered at runtime, i.e. these objects should only be constructed 587a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// when absolutely necessary, which means: 597a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// - For LOG() statements, when the corresponding log level is enabled. 607a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// - For CHECK(), when the tested expression doesn't hold. 617a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 627a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// At the same time, we really want to use expressions like: 637a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// LOG(severity) << some_stuff << some_more_stuff; 647a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 657a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// This means LOG(severity) should expand to something that can take 667a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// << operators on its right hand side. This is achieved with the 677a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// ternary '? :', as implemented by this helper macro. 68c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner// 697a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Unfortunately, a simple thing like: 707a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 717a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// !(condition) ? (void)0 : (expr) 727a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 737a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// will not work, because the compiler complains loudly with: 747a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 757a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// error: second operand to the conditional operator is of type 'void', 767a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// but the third operand is neither a throw-expression nor of type 'void' 777a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define LOG_LAZY_EVAL(condition, expr) \ 787a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner !(condition) ? (void)0 : ::android::base::LogStreamVoidify() & (expr) 797a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 807a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Send a message to the log if |severity| is higher or equal to the current 817a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// logging severity level. This macro expands to an expression that acts as 827a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// an input stream for strings, ints and floating point values, as well as 837a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// LogString instances. Usage example: 847a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 857a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// LOG(INFO) << "Starting flux capacitor"; 867a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// fluxCapacitor::start(); 877a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// LOG(INFO) << "Flux capacitor started"; 887a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 897a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Note that the macro implementation is optimized to avoid doing any work 907a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// if the severity level is disabled. 917a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 927a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// It's possible to do conditional logging with LOG_IF() 937a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define LOG(severity) \ 947a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LOG_LAZY_EVAL(LOG_IS_ON(severity), \ 957a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LOG_MESSAGE_STREAM_COMPACT(severity)) 96c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 977a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// A variant of LOG() that only performs logging if a specific condition 987a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// is encountered. Note that |condition| is only evaluated if |severity| 997a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// is high enough. Usage example: 1007a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 1017a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// LOG(INFO) << "Starting fuel injector"; 1027a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// fuelInjector::start(); 1037a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// LOG(INFO) << "Fuel injection started"; 1047a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// LOG_IF(INFO, fuelInjector::hasOptimalLevel()) 1057a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// << "Fuel injection at optimal level"; 1067a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 1077a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define LOG_IF(severity, condition) \ 1087a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), \ 1097a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LOG_MESSAGE_STREAM_COMPACT(severity)) 1107a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 1117a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 1127a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// A variant of LOG() that also appends the string message corresponding 1137a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// to the current value of 'errno' just before the macro is called. This 1147a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// also preserves the value of 'errno' so it can be tested after the 1157a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// macro call (i.e. any error during log output does not interfere). 1167a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define PLOG(severity) \ 1177a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LOG_LAZY_EVAL(LOG_IS_ON(severity), \ 1187a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner PLOG_MESSAGE_STREAM_COMPACT(severity)) 1197a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 1207a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// A variant of LOG_IF() that also appends the string message corresponding 1217a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// to the current value of 'errno' just before the macro is called. This 1227a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// also preserves the value of 'errno' so it can be tested after the 1237a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// macro call (i.e. any error during log output does not interfere). 1247a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define PLOG_IF(severity, condition) \ 1257a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), \ 1267a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner PLOG_MESSAGE_STREAM_COMPACT(severity)) 127c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 1287a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Evaluate |condition|, and if it fails, log a fatal message. 1297a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// This is a better version of assert(), in the future, this will 1307a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// also break directly into the debugger for debug builds. 1317a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 1327a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Usage is similar to LOG(FATAL), e.g.: 1337a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 1347a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// CHECK(some_condition) << "Something really bad happened!"; 1357a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 1367a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define CHECK(condition) \ 1377a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " 1387a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 1397a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 1407a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// A variant of CHECK() that also appends the errno message string at 1417a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// the end of the log message before exiting the process. 1427a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define PCHECK(condition) \ 1437a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner PLOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " 1447a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 1457a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 1467a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Define ENABLE_DLOG to 1 here if DLOG() statements should be compiled 1477a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// as normal LOG() ones in the final binary. If 0, the statements will not 1487a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// be compiled. 1497a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#ifndef ENABLE_DLOG 1507a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# if defined(NDEBUG) 1517a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# define ENABLE_DLOG 0 1527a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# else 1537a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# define ENABLE_DLOG 1 1547a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# endif 1557a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#endif 1567a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 1577a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// ENABLE_DCHECK controls how DCHECK() statements are compiled: 1587a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 0 - DCHECK() are not compiled in the binary at all. 1597a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 1 - DCHECK() are compiled, but are not performed at runtime, unless 1607a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// the DCHECK level has been increased explicitely. 1617a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 2 - DCHECK() are always compiled as CHECK() in the final binary. 1627a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#ifndef ENABLE_DCHECK 1637a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# if defined(NDEBUG) 1647a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# define ENABLE_DCHECK 1 1657a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# else 1667a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# define ENABLE_DCHECK 2 1677a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# endif 1687a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#endif 169c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 1707a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// DLOG_IS_ON(severity) is used to indicate whether DLOG() should print 1717a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// something for the current level. 1727a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#if ENABLE_DLOG 1737a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# define DLOG_IS_ON(severity) LOG_IS_ON(severity) 1747a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#else 1757a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// NOTE: The compile-time constant ensures that the DLOG() statements are 1767a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// not compiled in the final binary. 1777a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# define DLOG_IS_ON(severity) false 1787a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#endif 179c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 1807a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// DCHECK_IS_ON() is used to indicate whether DCHECK() should do anything. 1817a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#if ENABLE_DCHECK == 0 1827a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // NOTE: Compile-time constant ensures the DCHECK() statements are 1837a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // note compiled in the final binary. 1847a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# define DCHECK_IS_ON() false 1857a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#elif ENABLE_DCHECK == 1 1867a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# define DCHECK_IS_ON() ::android::base::dcheckIsEnabled() 1877a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#else 1887a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner# define DCHECK_IS_ON() true 1897a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#endif 1907a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 1917a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// A function that returns true iff DCHECK() should actually do any checking. 1927a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerbool dcheckIsEnabled(); 1937a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 1947a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Change the DCHECK() level to either false or true. Should only be called 1957a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// early, e.g. after parsing command-line arguments. Returns previous value. 1967a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerbool setDcheckLevel(bool enabled); 1977a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 1987a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// DLOG() is like LOG() for debug builds, and doesn't do anything for 1997a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// release one. This is useful to add log messages that you don't want 2007a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// to see in the final binaries, but are useful during testing. 2017a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define DLOG(severity) LOG_IF(severity, DLOG_IS_ON()) 2027a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 2037a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// DLOG_IF() is like DLOG() for debug builds, and doesn't do anything for 2047a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// release one. See DLOG() comments. 2057a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define DLOG_IF(severity, condition) \ 2067a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LOG_IF(severity, DLOG_IS_ON() && (condition)) 2077a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 2087a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// DCHECK(condition) is used to perform CHECK() in debug builds, or if 2097a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// the program called setDcheckLevel(true) previously. Note that it is 2107a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// also possible to completely remove them from the final binary by 2117a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// using the compiler flag -DENABLE_DCHECK=0 2127a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define DCHECK(condition) \ 2137a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LOG_IF(FATAL, DCHECK_IS_ON() && !(condition)) \ 2147a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner << "Check failed: " #condition ". " 215c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 2167a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Convenience class used hold a formatted string for logging reasons. 2177a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Usage example: 2187a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 2197a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// LOG(INFO) << LogString("There are %d items in this set", count); 2207a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 2217a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerclass LogString { 2227a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerpublic: 2237a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogString(const char* fmt, ...); 2247a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner ~LogString(); 2257a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner const char* string() const { return mString; } 2267a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerprivate: 2277a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner char* mString; 2287a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner}; 2297a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 2307a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Helper structure used to group the parameters of a LOG() or CHECK() 2317a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// statement. 2327a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerstruct LogParams { 2337a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogParams() : file(NULL), lineno(-1), severity(-1) {} 2347a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 2357a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogParams(const char* a_file, int a_lineno, LogSeverity a_severity) 2367a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner : file(a_file), lineno(a_lineno), severity(a_severity) {} 2377a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 2387a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner const char* file; 2397a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner int lineno; 2407a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogSeverity severity; 2417a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner}; 2427a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 2437a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Helper class used to implement an input stream similar to std::istream 2447a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// where it's possible to inject strings, integers, floats and LogString 2457a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// instances with the << operator. 2467a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 2477a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// This also takes a source file, line number and severity to avoid 2487a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// storing these in the stack of the functions were LOG() and CHECK() 2497a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// statements are called. 2507a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerclass LogStream { 2517a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerpublic: 2527a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream(const char* file, int lineno, LogSeverity severity); 2537a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner ~LogStream(); 254c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 2557a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner inline LogStream& operator<<(const char* str) { 2567a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner append(str); 2577a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner return *this; 2587a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner } 2597a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 2607a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner inline LogStream& operator<<(const LogString& str) { 2617a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner append(str.string()); 2627a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner return *this; 2637a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner } 2647a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 2657a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // Note: this prints the pointer value (address). 2667a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream& operator<<(const void* v); 2677a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 2687a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream& operator<<(char ch); 2697a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream& operator<<(int v); 2707a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream& operator<<(unsigned v); 2717a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream& operator<<(long v); 2727a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream& operator<<(unsigned long v); 2737a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner //LogStream& operator<<(size_t v); 2747a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream& operator<<(long long v); 2757a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream& operator<<(unsigned long long v); 2767a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream& operator<<(float v); 2777a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream& operator<<(double v); 278c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 2797a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner const char* string() const { return mString ? mString : ""; } 2807a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner size_t size() const { return mSize; } 2817a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner const LogParams& params() const { return mParams; } 2827a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 2837a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerprivate: 2847a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner void append(const char* str); 2857a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner void append(const char* str, size_t len); 2867a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 2877a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogParams mParams; 2887a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner char* mString; 2897a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner size_t mSize; 2907a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner size_t mCapacity; 2917a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner}; 2927a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 2937a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Helper class used to avoid compiler errors, see LOG_LAZY_EVAL for 2947a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// more information. 2957a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerclass LogStreamVoidify { 2967a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner public: 2977a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStreamVoidify() { } 2987a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // This has to be an operator with a precedence lower than << but 2997a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // higher than ?: 3007a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner void operator&(LogStream&) { } 3017a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner}; 3027a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3037a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// This represents an log message. At creation time, provide the name of 3047a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// the current file, the source line number and a severity. 3057a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// You can them stream stuff into it with <<. For example: 3067a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 3077a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// LogMessage(__FILE__, __LINE__, LOG_INFO) << "Hello World!\n"; 3087a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 3097a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// When destroyed, the message sends the final output to the appropriate 3107a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// log (e.g. stderr by default). 3117a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerclass LogMessage { 3127a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerpublic: 3137a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogMessage(const char* file, int line, LogSeverity severity); 3147a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner ~LogMessage(); 3157a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3167a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream& stream() const { return *mStream; } 3177a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerprotected: 3187a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // Avoid that each LOG() statement 3197a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream* mStream; 3207a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner}; 3217a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3227a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Helper macros to avoid too much typing. This creates a new LogMessage 3237a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// instance with the appropriate file source path, file source line and 3247a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// severity. 3257a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define LOG_MESSAGE_COMPACT(severity) \ 3267a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner ::android::base::LogMessage( \ 3277a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner __FILE__, \ 3287a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner __LINE__, \ 3297a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner ::android::base::LOG_ ## severity) 3307a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3317a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define LOG_MESSAGE_STREAM_COMPACT(severity) \ 3327a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LOG_MESSAGE_COMPACT(severity).stream() 3337a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3347a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3357a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// A variant of LogMessage that saves the errno value on creation, 3367a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// then restores it on destruction, as well as append a strerror() 3377a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// error message to the log before sending it for output. Used by 3387a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// the PLOG() implementation(s). 3397a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// 3407a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// This cannot be a sub-class of LogMessage because the destructor needs 3417a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// to restore the saved errno message after sending the message to the 3427a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// LogOutput and deleting the stream. 3437a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerclass ErrnoLogMessage { 3447a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerpublic: 3457a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner ErrnoLogMessage(const char* file, 3467a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner int line, 3477a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogSeverity severity, 3487a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner int errnoCode); 3497a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner ~ErrnoLogMessage(); 350c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 3517a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream& stream() const { return *mStream; } 3527a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerprivate: 3537a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogStream* mStream; 3547a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner int mErrno; 3557a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner}; 3567a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3577a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Helper macros to avoid too much typing. 3587a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define PLOG_MESSAGE_COMPACT(severity) \ 3597a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner ::android::base::ErrnoLogMessage( \ 3607a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner __FILE__, \ 3617a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner __LINE__, \ 3627a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner ::android::base::LOG_ ## severity, \ 3637a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner errno) 3647a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3657a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#define PLOG_MESSAGE_STREAM_COMPACT(severity) \ 3667a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner PLOG_MESSAGE_COMPACT(severity).stream() 3677a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3687a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnernamespace testing { 3697a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3707a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// Abstract interface to the output where the log messages are sent. 3717a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner// IMPORTANT: Only use this for unit testing the log facility. 3727a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turnerclass LogOutput { 373c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turnerpublic: 3747a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner LogOutput() {} 3757a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner virtual ~LogOutput() {} 376c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 3777a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // Send a full log message to the output. Not zero terminated, and 3787a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // Does not have a trailing \n which can be added by the implementation 3797a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // when writing the message to a file. 3807a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // Note: if |severity| is LOG_FATAL, this should also terminate the 3817a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // process. 3827a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner virtual void logMessage(const LogParams& params, 3837a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner const char* message, 3847a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner size_t message_len) = 0; 385c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 3867a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // Set a new log output, and return pointer to the previous 3877a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // implementation, which will be NULL for the default one. 3887a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // |newOutput| is either NULL (which means the default), or a 3897a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner // custom instance of LogOutput. 3907a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner static LogOutput* setNewOutput(LogOutput* newOutput); 3917a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner}; 3927a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3937a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner} // namespace testing 3947a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3957a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner} // namespace base 3967a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner} // namespace android 3977a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner 3987a41eef6b64b2a07cf170844c897e4ae1cda998eDavid 'Digit' Turner#endif // ANDROID_BASE_LOG_H 399