1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.messaging.util; 18 19 /** 20 * Log utility class. 21 */ 22 public class LogUtil { 23 public static final String BUGLE_TAG = "MessagingApp"; 24 public static final String PROFILE_TAG = "MessagingAppProf"; 25 public static final String BUGLE_DATABASE_TAG = "MessagingAppDb"; 26 public static final String BUGLE_DATABASE_PERF_TAG = "MessagingAppDbPerf"; 27 public static final String BUGLE_DATAMODEL_TAG = "MessagingAppDataModel"; 28 public static final String BUGLE_IMAGE_TAG = "MessagingAppImage"; 29 public static final String BUGLE_NOTIFICATIONS_TAG = "MessagingAppNotif"; 30 public static final String BUGLE_WIDGET_TAG = "MessagingAppWidget"; 31 32 public static final int DEBUG = android.util.Log.DEBUG; 33 public static final int WARN = android.util.Log.WARN; 34 public static final int VERBOSE = android.util.Log.VERBOSE; 35 public static final int INFO = android.util.Log.INFO; 36 public static final int ERROR = android.util.Log.ERROR; 37 38 // If this is non-null, DEBUG and higher logs will be tracked in-memory. It will not include 39 // VERBOSE logs. 40 private static LogSaver sDebugLogSaver; 41 private static volatile boolean sCaptureDebugLogs; 42 43 /** 44 * Read Gservices to see if logging should be enabled. 45 */ refreshGservices(final BugleGservices gservices)46 public static void refreshGservices(final BugleGservices gservices) { 47 sCaptureDebugLogs = gservices.getBoolean( 48 BugleGservicesKeys.ENABLE_LOG_SAVER, 49 BugleGservicesKeys.ENABLE_LOG_SAVER_DEFAULT); 50 if (sCaptureDebugLogs && (sDebugLogSaver == null || !sDebugLogSaver.isCurrent())) { 51 // We were not capturing logs before. We are now. 52 sDebugLogSaver = LogSaver.newInstance(); 53 } else if (!sCaptureDebugLogs && sDebugLogSaver != null) { 54 // We were capturing logs. We aren't anymore. 55 sDebugLogSaver = null; 56 } 57 } 58 59 // This is called from FactoryImpl once the Gservices class is initialized. initializeGservices(final BugleGservices gservices)60 public static void initializeGservices (final BugleGservices gservices) { 61 gservices.registerForChanges(new Runnable() { 62 @Override 63 public void run() { 64 refreshGservices(gservices); 65 } 66 }); 67 refreshGservices(gservices); 68 } 69 70 /** 71 * Send a {@link #VERBOSE} log message. 72 * @param tag Used to identify the source of a log message. It usually identifies 73 * the class or activity where the log call occurs. 74 * @param msg The message you would like logged. 75 */ v(final String tag, final String msg)76 public static void v(final String tag, final String msg) { 77 println(android.util.Log.VERBOSE, tag, msg); 78 } 79 80 /** 81 * Send a {@link #VERBOSE} log message. 82 * @param tag Used to identify the source of a log message. It usually identifies 83 * the class or activity where the log call occurs. 84 * @param msg The message you would like logged. 85 * @param tr An exception to log 86 */ v(final String tag, final String msg, final Throwable tr)87 public static void v(final String tag, final String msg, final Throwable tr) { 88 println(android.util.Log.VERBOSE, tag, msg + '\n' 89 + android.util.Log.getStackTraceString(tr)); 90 } 91 92 /** 93 * Send a {@link #DEBUG} log message. 94 * @param tag Used to identify the source of a log message. It usually identifies 95 * the class or activity where the log call occurs. 96 * @param msg The message you would like logged. 97 */ d(final String tag, final String msg)98 public static void d(final String tag, final String msg) { 99 println(android.util.Log.DEBUG, tag, msg); 100 } 101 102 /** 103 * Send a {@link #DEBUG} log message and log the exception. 104 * @param tag Used to identify the source of a log message. It usually identifies 105 * the class or activity where the log call occurs. 106 * @param msg The message you would like logged. 107 * @param tr An exception to log 108 */ d(final String tag, final String msg, final Throwable tr)109 public static void d(final String tag, final String msg, final Throwable tr) { 110 println(android.util.Log.DEBUG, tag, msg + '\n' 111 + android.util.Log.getStackTraceString(tr)); 112 } 113 114 /** 115 * Send an {@link #INFO} log message. 116 * @param tag Used to identify the source of a log message. It usually identifies 117 * the class or activity where the log call occurs. 118 * @param msg The message you would like logged. 119 */ i(final String tag, final String msg)120 public static void i(final String tag, final String msg) { 121 println(android.util.Log.INFO, tag, msg); 122 } 123 124 /** 125 * Send a {@link #INFO} log message and log the exception. 126 * @param tag Used to identify the source of a log message. It usually identifies 127 * the class or activity where the log call occurs. 128 * @param msg The message you would like logged. 129 * @param tr An exception to log 130 */ i(final String tag, final String msg, final Throwable tr)131 public static void i(final String tag, final String msg, final Throwable tr) { 132 println(android.util.Log.INFO, tag, msg + '\n' 133 + android.util.Log.getStackTraceString(tr)); 134 } 135 136 /** 137 * Send a {@link #WARN} log message. 138 * @param tag Used to identify the source of a log message. It usually identifies 139 * the class or activity where the log call occurs. 140 * @param msg The message you would like logged. 141 */ w(final String tag, final String msg)142 public static void w(final String tag, final String msg) { 143 println(android.util.Log.WARN, tag, msg); 144 } 145 146 /** 147 * Send a {@link #WARN} log message and log the exception. 148 * @param tag Used to identify the source of a log message. It usually identifies 149 * the class or activity where the log call occurs. 150 * @param msg The message you would like logged. 151 * @param tr An exception to log 152 */ w(final String tag, final String msg, final Throwable tr)153 public static void w(final String tag, final String msg, final Throwable tr) { 154 println(android.util.Log.WARN, tag, msg); 155 println(android.util.Log.WARN, tag, android.util.Log.getStackTraceString(tr)); 156 } 157 158 /** 159 * Send an {@link #ERROR} log message. 160 * @param tag Used to identify the source of a log message. It usually identifies 161 * the class or activity where the log call occurs. 162 * @param msg The message you would like logged. 163 */ e(final String tag, final String msg)164 public static void e(final String tag, final String msg) { 165 println(android.util.Log.ERROR, tag, msg); 166 } 167 168 /** 169 * Send a {@link #ERROR} log message and log the exception. 170 * @param tag Used to identify the source of a log message. It usually identifies 171 * the class or activity where the log call occurs. 172 * @param msg The message you would like logged. 173 * @param tr An exception to log 174 */ e(final String tag, final String msg, final Throwable tr)175 public static void e(final String tag, final String msg, final Throwable tr) { 176 println(android.util.Log.ERROR, tag, msg); 177 println(android.util.Log.ERROR, tag, android.util.Log.getStackTraceString(tr)); 178 } 179 180 /** 181 * What a Terrible Failure: Report a condition that should never happen. 182 * The error will always be logged at level ASSERT with the call stack. 183 * Depending on system configuration, a report may be added to the 184 * {@link android.os.DropBoxManager} and/or the process may be terminated 185 * immediately with an error dialog. 186 * @param tag Used to identify the source of a log message. 187 * @param msg The message you would like logged. 188 */ wtf(final String tag, final String msg)189 public static void wtf(final String tag, final String msg) { 190 // Make sure this goes into our log buffer 191 println(android.util.Log.ASSERT, tag, "wtf\n" + msg); 192 android.util.Log.wtf(tag, msg, new Exception()); 193 } 194 195 /** 196 * What a Terrible Failure: Report a condition that should never happen. 197 * The error will always be logged at level ASSERT with the call stack. 198 * Depending on system configuration, a report may be added to the 199 * {@link android.os.DropBoxManager} and/or the process may be terminated 200 * immediately with an error dialog. 201 * @param tag Used to identify the source of a log message. 202 * @param msg The message you would like logged. 203 * @param tr An exception to log 204 */ wtf(final String tag, final String msg, final Throwable tr)205 public static void wtf(final String tag, final String msg, final Throwable tr) { 206 // Make sure this goes into our log buffer 207 println(android.util.Log.ASSERT, tag, "wtf\n" + msg + '\n' + 208 android.util.Log.getStackTraceString(tr)); 209 android.util.Log.wtf(tag, msg, tr); 210 } 211 212 /** 213 * Low-level logging call. 214 * @param level The priority/type of this log message 215 * @param tag Used to identify the source of a log message. It usually identifies 216 * the class or activity where the log call occurs. 217 * @param msg The message you would like logged. 218 */ println(final int level, final String tag, final String msg)219 private static void println(final int level, final String tag, final String msg) { 220 android.util.Log.println(level, tag, msg); 221 222 LogSaver serviceLog = sDebugLogSaver; 223 if (serviceLog != null && level >= android.util.Log.DEBUG) { 224 serviceLog.log(level, tag, msg); 225 } 226 } 227 228 /** 229 * Save logging into LogSaver only, for dumping to bug report 230 * 231 * @param level The priority/type of this log message 232 * @param tag Used to identify the source of a log message. It usually identifies 233 * the class or activity where the log call occurs. 234 * @param msg The message you would like logged. 235 */ save(final int level, final String tag, final String msg)236 public static void save(final int level, final String tag, final String msg) { 237 LogSaver serviceLog = sDebugLogSaver; 238 if (serviceLog != null) { 239 serviceLog.log(level, tag, msg); 240 } 241 } 242 243 /** 244 * Checks to see whether or not a log for the specified tag is loggable at the specified level. 245 * See {@link android.util.Log#isLoggable(String, int)} for more discussion. 246 */ isLoggable(final String tag, final int level)247 public static boolean isLoggable(final String tag, final int level) { 248 return android.util.Log.isLoggable(tag, level); 249 } 250 251 /** 252 * Returns text as is if {@value #BUGLE_TAG}'s log level is set to DEBUG or VERBOSE; 253 * returns "--" otherwise. Useful for log statements where we don't want to log 254 * various strings (e.g., usernames) with default logging to avoid leaking PII in logcat. 255 */ sanitizePII(final String text)256 public static String sanitizePII(final String text) { 257 if (text == null) { 258 return null; 259 } 260 261 if (android.util.Log.isLoggable(BUGLE_TAG, android.util.Log.DEBUG)) { 262 return text; 263 } else { 264 return "Redacted-" + text.length(); 265 } 266 } 267 dump(java.io.PrintWriter out)268 public static void dump(java.io.PrintWriter out) { 269 final LogSaver logsaver = sDebugLogSaver; 270 if (logsaver != null) { 271 logsaver.dump(out); 272 } 273 } 274 } 275