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