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 mIsEngBuild; 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 isEngBuild, boolean logSensitive)45 Log(String tag, boolean isEngBuild, boolean logSensitive) { 46 this.mTAG = tag; 47 this.mIsEngBuild = isEngBuild; 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 /** 222 * What a Terrible Failure: Report a condition that should never happen. 223 * The error will always be logged at level ASSERT with the call stack. 224 * Depending on system configuration, a report may be added to the 225 * {@link android.os.DropBoxManager} and/or the process may be terminated 226 * immediately with an error dialog. 227 * 228 * @param prefix the String prefix to be used for this log entry 229 * @param msg the String msg to be logged 230 * @param tr an Exception to log 231 */ wtf(String prefix, String msg, Throwable tr)232 public void wtf(String prefix, String msg, Throwable tr) { 233 android.util.Log.wtf(mTAG, prefix + ": " + msg, tr); 234 } 235 236 /** 237 * Returns a String-formatted version of the given PII. 238 * 239 * <p>Depending on the logging configurations and build-type, the returned PII may be 240 * obfuscated. 241 * 242 * @param pii the PII to be formatted 243 * @return the String-formatted version of the PII 244 */ pii(Object pii)245 public String pii(Object pii) { 246 if (!mIsEngBuild || !mLogSensitive) { 247 return String.valueOf(Objects.hashCode(pii)); 248 } else { 249 if (pii instanceof byte[]) { 250 return byteArrayToHexString((byte[]) pii); 251 } 252 return String.valueOf(pii); 253 } 254 } 255 256 /** 257 * Checks whether the given logging level (defined in {@link android.util.Log}) is loggable for 258 * this Log. 259 * 260 * @param level the logging level to be checked for being loggable 261 * @return true iff level is at the configured logging level or higher 262 */ isLoggable(int level)263 private boolean isLoggable(int level) { 264 return android.util.Log.isLoggable(mTAG, level); 265 } 266 267 /** 268 * Returns the hex-String representation of the given byte[]. 269 * 270 * @param data the byte[] to be represented 271 * @return the String representation of data 272 */ byteArrayToHexString(byte[] data)273 public static String byteArrayToHexString(byte[] data) { 274 if (data == null || data.length == 0) { 275 return ""; 276 } 277 278 StringBuilder sb = new StringBuilder(); 279 for (byte b : data) { 280 sb.append(String.format(Locale.US, "%02X", b)); 281 } 282 return sb.toString(); 283 } 284 } 285