|
| 1 | +/* |
| 2 | +* Copyright (c) 2013 Google, Inc. |
| 3 | +* |
| 4 | +* This software is provided 'as-is', without any express or implied |
| 5 | +* warranty. In no event will the authors be held liable for any damages |
| 6 | +* arising from the use of this software. |
| 7 | +* Permission is granted to anyone to use this software for any purpose, |
| 8 | +* including commercial applications, and to alter it and redistribute it |
| 9 | +* freely, subject to the following restrictions: |
| 10 | +* 1. The origin of this software must not be misrepresented; you must not |
| 11 | +* claim that you wrote the original software. If you use this software |
| 12 | +* in a product, an acknowledgment in the product documentation would be |
| 13 | +* appreciated but is not required. |
| 14 | +* 2. Altered source versions must be plainly marked as such, and must not be |
| 15 | +* misrepresented as being the original software. |
| 16 | +* 3. This notice may not be removed or altered from any source distribution. |
| 17 | +*/ |
| 18 | +#ifndef ANDROID_LOG_PRINT_H |
| 19 | +#define ANDROID_LOG_PRINT_H |
| 20 | + |
| 21 | +// This header redefines printf to send data to Android's log stream and |
| 22 | +// provides an implementation of std::ostream which prints to the Android |
| 23 | +// log output. |
| 24 | +// |
| 25 | +// For example: |
| 26 | +// |
| 27 | +// #include "AndroidUtil/AndroidLogPrint.h" |
| 28 | +// #include "AndroidUtil/AndroidMainWrapper.h" |
| 29 | +// |
| 30 | +// int main(int argc, char **argv) { |
| 31 | +// gAndroidLogPrintfTag = "my_application"; |
| 32 | +// printf("Print to the log from printf\n"); |
| 33 | +// AndroidLogPrintStreamBuf streambuf; |
| 34 | +// std::ostream stream(&streambuf); |
| 35 | +// stream << "Print to the log from a stream\n"); |
| 36 | +// return 0; |
| 37 | +// } |
| 38 | +// |
| 39 | +// will print "Print to the log from printf" and |
| 40 | +// "Print to the log from a stream" to Android's log stream which can be viewed |
| 41 | +// using "adb logcat". All log messages from the application will be prefixed |
| 42 | +// with the tag, "my_application" so they can optionally extracted from |
| 43 | +// "adb logcat" output. |
| 44 | + |
| 45 | +#if defined(ANDROID) || defined(__ANDROID__) |
| 46 | +#include <android/log.h> |
| 47 | +#include <stdarg.h> |
| 48 | + |
| 49 | +// If a log tag isn't specified, default to "main". |
| 50 | +// |
| 51 | +// Log tag can optionally be set when building this library by adding |
| 52 | +// -DANDROID_LOG_PRINT_TAG="mytag" to the ANDROIDUTIL_ADDITIONAL_CFLAGS |
| 53 | +// variable before importing this module into a NDK project. |
| 54 | +// |
| 55 | +// For example, an Android.mk to add the tag "myproject" to the log output |
| 56 | +// would look be: |
| 57 | +// |
| 58 | +// LOCAL_MODULE:=MyProject |
| 59 | +// LOCAL_SRC_FILES:=MyProject.cpp |
| 60 | +// LOCAL_STATIC_LIBRARIES:=android_native_app_glue libandroidutil_static |
| 61 | +// ANDROIDUTIL_ADDITIONAL_CFLAGS:=-DANDROID_LOG_PRINT_TAG="myproject" |
| 62 | +// include $(BUILD_SHARED_LIBRARY) |
| 63 | +// $(call import-module,AndroidUtil/jni) |
| 64 | +// $(call import-module,android/native_app_glue) |
| 65 | +// |
| 66 | +#if defined(ANDROID_LOG_PRINT_TAG) |
| 67 | +// Macros to expand ANDROID_LOG_PRINT_TAG as a string. |
| 68 | +#define ANDROID_LOG_PRINT_TAG_AS_STRING2(x) #x |
| 69 | +#define ANDROID_LOG_PRINT_TAG_AS_STRING(x) ANDROID_LOG_PRINT_TAG_AS_STRING2(x) |
| 70 | +#define ANDROID_LOG_PRINT_TAG_STRING \ |
| 71 | + ANDROID_LOG_PRINT_TAG_AS_STRING(ANDROID_LOG_PRINT_TAG) |
| 72 | +#else |
| 73 | +#define ANDROID_LOG_PRINT_TAG "main" |
| 74 | +#define ANDROID_LOG_PRINT_TAG_STRING ANDROID_LOG_PRINT_TAG |
| 75 | +#endif // !defined(ANDROID_LOG_PRINT_TAG) |
| 76 | + |
| 77 | +// The priority to use when printing to the Android log. If this isn't |
| 78 | +// specified it defaults to ANDROID_LOG_INFO. See android/log.h for more |
| 79 | +// information. |
| 80 | +// |
| 81 | +// For example: |
| 82 | +// #define ANDROID_LOG_PRINT_PRIORITY ANDROID_LOG_DEBUG |
| 83 | +// #include "android_log_print.h" |
| 84 | +#if !defined(ANDROID_LOG_PRINT_PRIORITY) |
| 85 | +#define ANDROID_LOG_PRINT_PRIORITY ANDROID_LOG_INFO |
| 86 | +#endif // !defined(ANDROID_LOG_PRINT_PRIORITY) |
| 87 | + |
| 88 | +// Enable / disable buffering of data written to the Android log. |
| 89 | +// NOTE: Log buffering in this module is not thread safe. |
| 90 | +// |
| 91 | +// For example: |
| 92 | +// #define ANDROID_LOG_PRINT_BUFFER 0 |
| 93 | +// #include "android_log_print.h" |
| 94 | +#if !defined(ANDROID_LOG_PRINT_BUFFER) |
| 95 | +#define ANDROID_LOG_PRINT_BUFFER 1 |
| 96 | +#endif // !defined(ANDROID_LOG_PRINT_BUFFER) |
| 97 | + |
| 98 | +// Whether to override printf() and vprintf() to redirect output to the android |
| 99 | +// log. |
| 100 | +#if !defined(ANDROID_LOG_OVERRIDE_PRINTF) |
| 101 | +#define ANDROID_LOG_OVERRIDE_PRINTF 1 |
| 102 | +#endif // !defined(ANDROID_LOG_OVERRIDE_PRINTF) |
| 103 | + |
| 104 | +// Redefine printf() and vprintf() to print to the Android log. |
| 105 | +#if ANDROID_LOG_OVERRIDE_PRINTF |
| 106 | +#if ANDROID_LOG_PRINT_BUFFER |
| 107 | +#define printf(...) AndroidPrintf(__VA_ARGS__) |
| 108 | +#define vprintf(format_, arg_) AndroidVPrintf(format_, arg_) |
| 109 | +#else |
| 110 | +#define printf(...) \ |
| 111 | + ((void)__android_log_print(ANDROID_LOG_PRINT_PRIORITY, \ |
| 112 | + gAndroidLogPrintfTag, __VA_ARGS__)) |
| 113 | +#define vprintf(format_, arg_) \ |
| 114 | + ((void)__android_log_vprint(ANDROID_LOG_PRINT_PRIORITY, \ |
| 115 | + gAndroidLogPrintfTag, format_, arg_)) |
| 116 | +#endif // ANDROID_LOG_PRINT_BUFFER |
| 117 | +#endif // ANDROID_LOG_OVERRIDE_PRINTF |
| 118 | + |
| 119 | +#if defined(__cplusplus) |
| 120 | +extern "C" { |
| 121 | +#endif // defined(__cplusplus) |
| 122 | + |
| 123 | +// Global tag used for log output. This can used when filtering the output of |
| 124 | +// "adb logcat" to distinguish the log messages from this application vs. |
| 125 | +// other applications and the rest of the system. |
| 126 | +extern const char *gAndroidLogPrintfTag; |
| 127 | + |
| 128 | +// Print to the log via a temporary buffer to workaround __android_log_print() |
| 129 | +// adding a newline to the end of each printed string. |
| 130 | +void AndroidVPrintf(const char *format, va_list arg); |
| 131 | +// See android_vprintf(). |
| 132 | +void AndroidPrintf(const char *format, ...); |
| 133 | + |
| 134 | +// Wrappers around AndroidVPrintf() and AndroidLogPrint() which ignore the |
| 135 | +// prio and tag arguments, instead using ANDROID_LOG_PRINT_PRIORITY and |
| 136 | +// ANDROID_LOG_PRINT_TAG. These can be used to replace __android_log_print |
| 137 | +// or __android_log_vprint in other modules. |
| 138 | +int AndroidLogVPrint(int prio, const char *tag, const char *fmt, va_list ap); |
| 139 | +int AndroidLogPrint(int prio, const char *tag, const char *fmt, ...); |
| 140 | + |
| 141 | +#if defined(__cplusplus) |
| 142 | +} |
| 143 | +#endif // defined(__cplusplus) |
| 144 | + |
| 145 | +#if defined(__cplusplus) |
| 146 | +#include <ostream> |
| 147 | +#include <streambuf> |
| 148 | + |
| 149 | +// Can be used to print to the Android log from a stream. |
| 150 | +// See the header comment for an example of how this class is used. |
| 151 | +class AndroidLogPrintStreamBuf : public std::streambuf { |
| 152 | + public: |
| 153 | + AndroidLogPrintStreamBuf() { } |
| 154 | + |
| 155 | + protected: |
| 156 | + // Print characters that are placed in the streambuf. |
| 157 | + virtual std::streamsize xsputn(const char *s, std::streamsize n) { |
| 158 | + for (std::streamsize i = 0; i < n; ++i) { |
| 159 | + printf("%c", s[i]); |
| 160 | + } |
| 161 | + return n; |
| 162 | + } |
| 163 | +}; |
| 164 | +#endif // defined(__cplusplus) |
| 165 | +#endif // defined(ANDROID) || defined(__ANDROID__) |
| 166 | +#endif // ANDROID_LOG_PRINT_H |
0 commit comments