1 /* 2 * Copyright (C) 2019 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.internal.net.utils; 18 19 import com.android.internal.annotations.VisibleForTesting; 20 21 import java.util.Locale; 22 import java.util.Objects; 23 24 /** 25 * Manages logging for all IKE packages. Wraps Android's Log class to prevent leakage of PII. 26 */ 27 public class Log { 28 private static final boolean VDBG = false; 29 30 private final String mTAG; 31 private final boolean mIsVdbg; 32 private final boolean mLogSensitive; 33 34 /** 35 * Constructs a Log instance configured with the given tag and logSensitive flag 36 * 37 * @param tag the String tag to be used for this Log's logging 38 * @param logSensitive boolean flag marking whether sensitive data (PII) should be logged 39 */ Log(String tag, boolean logSensitive)40 public Log(String tag, boolean logSensitive) { 41 this(tag, VDBG, logSensitive); 42 } 43 44 @VisibleForTesting Log(String tag, boolean isVdbg, boolean logSensitive)45 Log(String tag, boolean isVdbg, boolean logSensitive) { 46 this.mTAG = tag; 47 this.mIsVdbg = isVdbg; 48 this.mLogSensitive = logSensitive; 49 } 50 51 /** 52 * Logs the given prefix and msg Strings. 53 * 54 * <p>Note: Logging is only done if this instance's logging level is {@link 55 * android.util.Log#VERBOSE} or higher. 56 * 57 * @param prefix the String prefix to be used for this log entry 58 * @param msg the String msg to be logged 59 */ v(String prefix, String msg)60 public void v(String prefix, String msg) { 61 if (isLoggable(android.util.Log.VERBOSE)) { 62 android.util.Log.v(mTAG, prefix + ": " + msg); 63 } 64 } 65 66 /** 67 * Logs the given prefix and msg Strings. 68 * 69 * <p>Note: Logging is only done if this instance's logging level is {@link 70 * android.util.Log#VERBOSE} or higher. 71 * 72 * @param prefix the String prefix to be used for this log entry 73 * @param msg the String msg to be logged 74 * @param tr an Exception to log 75 */ v(String prefix, String msg, Throwable tr)76 public void v(String prefix, String msg, Throwable tr) { 77 if (isLoggable(android.util.Log.VERBOSE)) { 78 android.util.Log.v(mTAG, prefix + ": " + msg, tr); 79 } 80 } 81 82 /** 83 * Logs the given prefix and msg Strings. 84 * 85 * <p>Note: Logging is only done if this instance's logging level is {@link 86 * android.util.Log#DEBUG} or higher. 87 * 88 * @param prefix the String prefix to be used for this log entry 89 * @param msg the String msg to be logged 90 */ d(String prefix, String msg)91 public void d(String prefix, String msg) { 92 if (isLoggable(android.util.Log.DEBUG)) { 93 android.util.Log.d(mTAG, prefix + ": " + msg); 94 } 95 } 96 97 /** 98 * Logs the given prefix and msg Strings. 99 * 100 * <p>Note: Logging is only done if this instance's logging level is {@link 101 * android.util.Log#DEBUG} or higher. 102 * 103 * @param prefix the String prefix to be used for this log entry 104 * @param msg the String msg to be logged 105 * @param tr an Exception to log 106 */ d(String prefix, String msg, Throwable tr)107 public void d(String prefix, String msg, Throwable tr) { 108 if (isLoggable(android.util.Log.DEBUG)) { 109 android.util.Log.d(mTAG, prefix + ": " + msg, tr); 110 } 111 } 112 113 /** 114 * Logs the given prefix and msg Strings. 115 * 116 * <p>Note: Logging is only done if this instance's logging level is {@link 117 * android.util.Log#INFO} or higher. 118 * 119 * @param prefix the String prefix to be used for this log entry 120 * @param msg the String msg to be logged 121 */ i(String prefix, String msg)122 public void i(String prefix, String msg) { 123 if (isLoggable(android.util.Log.INFO)) { 124 android.util.Log.i(mTAG, prefix + ": " + msg); 125 } 126 } 127 128 /** 129 * Logs the given prefix and msg Strings. 130 * 131 * <p>Note: Logging is only done if this instance's logging level is {@link 132 * android.util.Log#INFO} or higher. 133 * 134 * @param prefix the String prefix to be used for this log entry 135 * @param msg the String msg to be logged 136 * @param tr an Exception to log 137 */ i(String prefix, String msg, Throwable tr)138 public void i(String prefix, String msg, Throwable tr) { 139 if (isLoggable(android.util.Log.INFO)) { 140 android.util.Log.i(mTAG, prefix + ": " + msg, tr); 141 } 142 } 143 144 /** 145 * Logs the given prefix and msg Strings. 146 * 147 * <p>Note: Logging is only done if this instance's logging level is {@link 148 * android.util.Log#WARN} or higher. 149 * 150 * @param prefix the String prefix to be used for this log entry 151 * @param msg the String msg to be logged 152 */ w(String prefix, String msg)153 public void w(String prefix, String msg) { 154 if (isLoggable(android.util.Log.WARN)) { 155 android.util.Log.w(mTAG, prefix + ": " + msg); 156 } 157 } 158 159 /** 160 * Logs the given prefix and msg Strings. 161 * 162 * <p>Note: Logging is only done if this instance's logging level is {@link 163 * android.util.Log#WARN} or higher. 164 * 165 * @param prefix the String prefix to be used for this log entry 166 * @param msg the String msg to be logged 167 * @param tr an Exception to log 168 */ w(String prefix, String msg, Throwable tr)169 public void w(String prefix, String msg, Throwable tr) { 170 if (isLoggable(android.util.Log.WARN)) { 171 android.util.Log.w(mTAG, prefix + ": " + msg, tr); 172 } 173 } 174 175 /** 176 * Logs the given prefix and msg Strings. 177 * 178 * <p>Note: Logging is only done if this instance's logging level is {@link 179 * android.util.Log#ERROR} or higher. 180 * 181 * @param prefix the String prefix to be used for this log entry 182 * @param msg the String msg to be logged 183 */ e(String prefix, String msg)184 public void e(String prefix, String msg) { 185 if (isLoggable(android.util.Log.ERROR)) { 186 android.util.Log.e(mTAG, prefix + ": " + msg); 187 } 188 } 189 190 /** 191 * Logs the given prefix and msg Strings. 192 * 193 * <p>Note: Logging is only done if this instance's logging level is {@link 194 * android.util.Log#ERROR} or higher. 195 * 196 * @param prefix the String prefix to be used for this log entry 197 * @param msg the String msg to be logged 198 * @param tr an Exception to log 199 */ e(String prefix, String msg, Throwable tr)200 public void e(String prefix, String msg, Throwable tr) { 201 if (isLoggable(android.util.Log.ERROR)) { 202 android.util.Log.e(mTAG, prefix + ": " + msg, tr); 203 } 204 } 205 206 /** 207 * What a Terrible Failure: Report a condition that should never happen. 208 * The error will always be logged at level ASSERT with the call stack. 209 * Depending on system configuration, a report may be added to the 210 * {@link android.os.DropBoxManager} and/or the process may be terminated 211 * immediately with an error dialog. 212 * 213 * @param prefix the String prefix to be used for this log entry 214 * @param msg the String msg to be logged 215 */ wtf(String prefix, String msg)216 public void wtf(String prefix, String msg) { 217 android.util.Log.wtf(mTAG, prefix + ": " + msg); 218 } 219 220 /** 221 * What a Terrible Failure: Report a condition that should never happen. 222 * The error will always be logged at level ASSERT with the call stack. 223 * Depending on system configuration, a report may be added to the 224 * {@link android.os.DropBoxManager} and/or the process may be terminated 225 * immediately with an error dialog. 226 * 227 * @param prefix the String prefix to be used for this log entry 228 * @param msg the String msg to be logged 229 * @param tr an Exception to log 230 */ wtf(String prefix, String msg, Throwable tr)231 public void wtf(String prefix, String msg, Throwable tr) { 232 android.util.Log.wtf(mTAG, prefix + ": " + msg, tr); 233 } 234 235 /** 236 * Returns a String-formatted version of the given PII. 237 * 238 * <p>Depending on the logging configurations and build-type, the returned PII may be 239 * obfuscated. 240 * 241 * @param pii the PII to be formatted 242 * @return the String-formatted version of the PII 243 */ pii(Object pii)244 public String pii(Object pii) { 245 if (!mIsVdbg || !mLogSensitive) { 246 return String.valueOf(Objects.hashCode(pii)); 247 } else { 248 if (pii instanceof byte[]) { 249 return byteArrayToHexString((byte[]) pii); 250 } 251 return String.valueOf(pii); 252 } 253 } 254 255 /** 256 * Checks whether the given logging level (defined in {@link android.util.Log}) is loggable for 257 * this Log. 258 * 259 * @param level the logging level to be checked for being loggable 260 * @return true iff level is at the configured logging level or higher 261 */ isLoggable(int level)262 private boolean isLoggable(int level) { 263 return android.util.Log.isLoggable(mTAG, level); 264 } 265 266 /** 267 * Returns the hex-String representation of the given byte[]. 268 * 269 * @param data the byte[] to be represented 270 * @return the String representation of data 271 */ byteArrayToHexString(byte[] data)272 public static String byteArrayToHexString(byte[] data) { 273 if (data == null || data.length == 0) { 274 return ""; 275 } 276 277 StringBuilder sb = new StringBuilder(); 278 for (byte b : data) { 279 sb.append(String.format(Locale.US, "%02X", b)); 280 } 281 return sb.toString(); 282 } 283 } 284