1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * <p>http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * <p>Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 * express or implied. See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 package com.android.voicemail.impl.mail.utils; 15 16 import android.net.Uri; 17 import android.support.annotation.VisibleForTesting; 18 import android.text.TextUtils; 19 import android.util.Log; 20 import com.android.voicemail.impl.VvmLog; 21 import java.util.List; 22 23 public class LogUtils { 24 public static final String TAG = "Email Log"; 25 26 private static final String ACCOUNT_PREFIX = "account:"; 27 28 /** Priority constant for the println method; use LogUtils.v. */ 29 public static final int VERBOSE = Log.VERBOSE; 30 31 /** Priority constant for the println method; use LogUtils.d. */ 32 public static final int DEBUG = Log.DEBUG; 33 34 /** Priority constant for the println method; use LogUtils.i. */ 35 public static final int INFO = Log.INFO; 36 37 /** Priority constant for the println method; use LogUtils.w. */ 38 public static final int WARN = Log.WARN; 39 40 /** Priority constant for the println method; use LogUtils.e. */ 41 public static final int ERROR = Log.ERROR; 42 43 /** 44 * Used to enable/disable logging that we don't want included in production releases. This should 45 * be set to DEBUG for production releases, and VERBOSE for internal builds. 46 */ 47 private static final int MAX_ENABLED_LOG_LEVEL = DEBUG; 48 49 private static Boolean debugLoggingEnabledForTests = null; 50 51 /** Enable debug logging for unit tests. */ 52 @VisibleForTesting setDebugLoggingEnabledForTests(boolean enabled)53 public static void setDebugLoggingEnabledForTests(boolean enabled) { 54 setDebugLoggingEnabledForTestsInternal(enabled); 55 } 56 setDebugLoggingEnabledForTestsInternal(boolean enabled)57 protected static void setDebugLoggingEnabledForTestsInternal(boolean enabled) { 58 debugLoggingEnabledForTests = Boolean.valueOf(enabled); 59 } 60 61 /** Returns true if the build configuration prevents debug logging. */ 62 @VisibleForTesting buildPreventsDebugLogging()63 public static boolean buildPreventsDebugLogging() { 64 return MAX_ENABLED_LOG_LEVEL > VERBOSE; 65 } 66 67 /** Returns a boolean indicating whether debug logging is enabled. */ isDebugLoggingEnabled(String tag)68 protected static boolean isDebugLoggingEnabled(String tag) { 69 if (buildPreventsDebugLogging()) { 70 return false; 71 } 72 if (debugLoggingEnabledForTests != null) { 73 return debugLoggingEnabledForTests.booleanValue(); 74 } 75 return Log.isLoggable(tag, Log.DEBUG) || Log.isLoggable(TAG, Log.DEBUG); 76 } 77 78 /** 79 * Returns a String for the specified content provider uri. This will do sanitation of the uri to 80 * remove PII if debug logging is not enabled. 81 */ contentUriToString(final Uri uri)82 public static String contentUriToString(final Uri uri) { 83 return contentUriToString(TAG, uri); 84 } 85 86 /** 87 * Returns a String for the specified content provider uri. This will do sanitation of the uri to 88 * remove PII if debug logging is not enabled. 89 */ contentUriToString(String tag, Uri uri)90 public static String contentUriToString(String tag, Uri uri) { 91 if (isDebugLoggingEnabled(tag)) { 92 // Debug logging has been enabled, so log the uri as is 93 return uri.toString(); 94 } else { 95 // Debug logging is not enabled, we want to remove the email address from the uri. 96 List<String> pathSegments = uri.getPathSegments(); 97 98 Uri.Builder builder = 99 new Uri.Builder() 100 .scheme(uri.getScheme()) 101 .authority(uri.getAuthority()) 102 .query(uri.getQuery()) 103 .fragment(uri.getFragment()); 104 105 // This assumes that the first path segment is the account 106 final String account = pathSegments.get(0); 107 108 builder = builder.appendPath(sanitizeAccountName(account)); 109 for (int i = 1; i < pathSegments.size(); i++) { 110 builder.appendPath(pathSegments.get(i)); 111 } 112 return builder.toString(); 113 } 114 } 115 116 /** Sanitizes an account name. If debug logging is not enabled, a sanitized name is returned. */ sanitizeAccountName(String accountName)117 public static String sanitizeAccountName(String accountName) { 118 if (TextUtils.isEmpty(accountName)) { 119 return ""; 120 } 121 122 return ACCOUNT_PREFIX + sanitizeName(TAG, accountName); 123 } 124 sanitizeName(final String tag, final String name)125 public static String sanitizeName(final String tag, final String name) { 126 if (TextUtils.isEmpty(name)) { 127 return ""; 128 } 129 130 if (isDebugLoggingEnabled(tag)) { 131 return name; 132 } 133 134 return String.valueOf(name.hashCode()); 135 } 136 137 /** 138 * Checks to see whether or not a log for the specified tag is loggable at the specified level. 139 */ isLoggable(String tag, int level)140 public static boolean isLoggable(String tag, int level) { 141 if (MAX_ENABLED_LOG_LEVEL > level) { 142 return false; 143 } 144 return Log.isLoggable(tag, level) || Log.isLoggable(TAG, level); 145 } 146 147 /** 148 * Send a {@link #VERBOSE} log message. 149 * 150 * @param tag Used to identify the source of a log message. It usually identifies the class or 151 * activity where the log call occurs. 152 * @param format the format string (see {@link java.util.Formatter#format}) 153 * @param args the list of arguments passed to the formatter. If there are more arguments than 154 * required by {@code format}, additional arguments are ignored. 155 */ v(String tag, String format, Object... args)156 public static void v(String tag, String format, Object... args) { 157 if (isLoggable(tag, VERBOSE)) { 158 VvmLog.v(tag, String.format(format, args)); 159 } 160 } 161 162 /** 163 * Send a {@link #VERBOSE} log message. 164 * 165 * @param tag Used to identify the source of a log message. It usually identifies the class or 166 * activity where the log call occurs. 167 * @param tr An exception to log 168 * @param format the format string (see {@link java.util.Formatter#format}) 169 * @param args the list of arguments passed to the formatter. If there are more arguments than 170 * required by {@code format}, additional arguments are ignored. 171 */ v(String tag, Throwable tr, String format, Object... args)172 public static void v(String tag, Throwable tr, String format, Object... args) { 173 if (isLoggable(tag, VERBOSE)) { 174 VvmLog.v(tag, String.format(format, args), tr); 175 } 176 } 177 178 /** 179 * Send a {@link #DEBUG} log message. 180 * 181 * @param tag Used to identify the source of a log message. It usually identifies the class or 182 * activity where the log call occurs. 183 * @param format the format string (see {@link java.util.Formatter#format}) 184 * @param args the list of arguments passed to the formatter. If there are more arguments than 185 * required by {@code format}, additional arguments are ignored. 186 */ d(String tag, String format, Object... args)187 public static void d(String tag, String format, Object... args) { 188 if (isLoggable(tag, DEBUG)) { 189 VvmLog.d(tag, String.format(format, args)); 190 } 191 } 192 193 /** 194 * Send a {@link #DEBUG} log message. 195 * 196 * @param tag Used to identify the source of a log message. It usually identifies the class or 197 * activity where the log call occurs. 198 * @param tr An exception to log 199 * @param format the format string (see {@link java.util.Formatter#format}) 200 * @param args the list of arguments passed to the formatter. If there are more arguments than 201 * required by {@code format}, additional arguments are ignored. 202 */ d(String tag, Throwable tr, String format, Object... args)203 public static void d(String tag, Throwable tr, String format, Object... args) { 204 if (isLoggable(tag, DEBUG)) { 205 VvmLog.d(tag, String.format(format, args), tr); 206 } 207 } 208 209 /** 210 * Send a {@link #INFO} log message. 211 * 212 * @param tag Used to identify the source of a log message. It usually identifies the class or 213 * activity where the log call occurs. 214 * @param format the format string (see {@link java.util.Formatter#format}) 215 * @param args the list of arguments passed to the formatter. If there are more arguments than 216 * required by {@code format}, additional arguments are ignored. 217 */ i(String tag, String format, Object... args)218 public static void i(String tag, String format, Object... args) { 219 if (isLoggable(tag, INFO)) { 220 VvmLog.i(tag, String.format(format, args)); 221 } 222 } 223 224 /** 225 * Send a {@link #INFO} log message. 226 * 227 * @param tag Used to identify the source of a log message. It usually identifies the class or 228 * activity where the log call occurs. 229 * @param tr An exception to log 230 * @param format the format string (see {@link java.util.Formatter#format}) 231 * @param args the list of arguments passed to the formatter. If there are more arguments than 232 * required by {@code format}, additional arguments are ignored. 233 */ i(String tag, Throwable tr, String format, Object... args)234 public static void i(String tag, Throwable tr, String format, Object... args) { 235 if (isLoggable(tag, INFO)) { 236 VvmLog.i(tag, String.format(format, args), tr); 237 } 238 } 239 240 /** 241 * Send a {@link #WARN} log message. 242 * 243 * @param tag Used to identify the source of a log message. It usually identifies the class or 244 * activity where the log call occurs. 245 * @param format the format string (see {@link java.util.Formatter#format}) 246 * @param args the list of arguments passed to the formatter. If there are more arguments than 247 * required by {@code format}, additional arguments are ignored. 248 */ w(String tag, String format, Object... args)249 public static void w(String tag, String format, Object... args) { 250 if (isLoggable(tag, WARN)) { 251 VvmLog.w(tag, String.format(format, args)); 252 } 253 } 254 255 /** 256 * Send a {@link #WARN} log message. 257 * 258 * @param tag Used to identify the source of a log message. It usually identifies the class or 259 * activity where the log call occurs. 260 * @param tr An exception to log 261 * @param format the format string (see {@link java.util.Formatter#format}) 262 * @param args the list of arguments passed to the formatter. If there are more arguments than 263 * required by {@code format}, additional arguments are ignored. 264 */ w(String tag, Throwable tr, String format, Object... args)265 public static void w(String tag, Throwable tr, String format, Object... args) { 266 if (isLoggable(tag, WARN)) { 267 VvmLog.w(tag, String.format(format, args), tr); 268 } 269 } 270 271 /** 272 * Send a {@link #ERROR} log message. 273 * 274 * @param tag Used to identify the source of a log message. It usually identifies the class or 275 * activity where the log call occurs. 276 * @param format the format string (see {@link java.util.Formatter#format}) 277 * @param args the list of arguments passed to the formatter. If there are more arguments than 278 * required by {@code format}, additional arguments are ignored. 279 */ e(String tag, String format, Object... args)280 public static void e(String tag, String format, Object... args) { 281 if (isLoggable(tag, ERROR)) { 282 VvmLog.e(tag, String.format(format, args)); 283 } 284 } 285 286 /** 287 * Send a {@link #ERROR} log message. 288 * 289 * @param tag Used to identify the source of a log message. It usually identifies the class or 290 * activity where the log call occurs. 291 * @param tr An exception to log 292 * @param format the format string (see {@link java.util.Formatter#format}) 293 * @param args the list of arguments passed to the formatter. If there are more arguments than 294 * required by {@code format}, additional arguments are ignored. 295 */ e(String tag, Throwable tr, String format, Object... args)296 public static void e(String tag, Throwable tr, String format, Object... args) { 297 if (isLoggable(tag, ERROR)) { 298 VvmLog.e(tag, String.format(format, args), tr); 299 } 300 } 301 302 /** 303 * What a Terrible Failure: Report a condition that should never happen. The error will always be 304 * logged at level ASSERT with the call stack. Depending on system configuration, a report may be 305 * added to the {@link android.os.DropBoxManager} and/or the process may be terminated immediately 306 * with an error dialog. 307 * 308 * @param tag Used to identify the source of a log message. It usually identifies the class or 309 * activity where the log call occurs. 310 * @param format the format string (see {@link java.util.Formatter#format}) 311 * @param args the list of arguments passed to the formatter. If there are more arguments than 312 * required by {@code format}, additional arguments are ignored. 313 */ wtf(String tag, String format, Object... args)314 public static void wtf(String tag, String format, Object... args) { 315 VvmLog.wtf(tag, String.format(format, args), new Error()); 316 } 317 318 /** 319 * What a Terrible Failure: Report a condition that should never happen. The error will always be 320 * logged at level ASSERT with the call stack. Depending on system configuration, a report may be 321 * added to the {@link android.os.DropBoxManager} and/or the process may be terminated immediately 322 * with an error dialog. 323 * 324 * @param tag Used to identify the source of a log message. It usually identifies the class or 325 * activity where the log call occurs. 326 * @param tr An exception to log 327 * @param format the format string (see {@link java.util.Formatter#format}) 328 * @param args the list of arguments passed to the formatter. If there are more arguments than 329 * required by {@code format}, additional arguments are ignored. 330 */ wtf(String tag, Throwable tr, String format, Object... args)331 public static void wtf(String tag, Throwable tr, String format, Object... args) { 332 VvmLog.wtf(tag, String.format(format, args), tr); 333 } 334 byteToHex(int b)335 public static String byteToHex(int b) { 336 return byteToHex(new StringBuilder(), b).toString(); 337 } 338 byteToHex(StringBuilder sb, int b)339 public static StringBuilder byteToHex(StringBuilder sb, int b) { 340 b &= 0xFF; 341 sb.append("0123456789ABCDEF".charAt(b >> 4)); 342 sb.append("0123456789ABCDEF".charAt(b & 0xF)); 343 return sb; 344 } 345 } 346