1 /* 2 * Copyright (C) 2013 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.incallui; 18 19 import android.net.Uri; 20 import android.telecom.PhoneAccount; 21 import android.telephony.PhoneNumberUtils; 22 23 import java.security.MessageDigest; 24 import java.security.NoSuchAlgorithmException; 25 26 /** 27 * Manages logging for the entire class. 28 */ 29 public class Log { 30 31 // Generic tag for all In Call logging 32 public static final String TAG = "InCall"; 33 34 public static final boolean FORCE_DEBUG = false; /* STOPSHIP if true */ 35 public static final boolean DEBUG = FORCE_DEBUG || 36 android.util.Log.isLoggable(TAG, android.util.Log.DEBUG); 37 public static final boolean VERBOSE = FORCE_DEBUG || 38 android.util.Log.isLoggable(TAG, android.util.Log.VERBOSE); 39 public static final String TAG_DELIMETER = " - "; 40 d(String tag, String msg)41 public static void d(String tag, String msg) { 42 if (DEBUG) { 43 android.util.Log.d(TAG, delimit(tag) + msg); 44 } 45 } 46 d(Object obj, String msg)47 public static void d(Object obj, String msg) { 48 if (DEBUG) { 49 android.util.Log.d(TAG, getPrefix(obj) + msg); 50 } 51 } 52 d(Object obj, String str1, Object str2)53 public static void d(Object obj, String str1, Object str2) { 54 if (DEBUG) { 55 android.util.Log.d(TAG, getPrefix(obj) + str1 + str2); 56 } 57 } 58 v(Object obj, String msg)59 public static void v(Object obj, String msg) { 60 if (VERBOSE) { 61 android.util.Log.v(TAG, getPrefix(obj) + msg); 62 } 63 } 64 v(Object obj, String str1, Object str2)65 public static void v(Object obj, String str1, Object str2) { 66 if (VERBOSE) { 67 android.util.Log.d(TAG, getPrefix(obj) + str1 + str2); 68 } 69 } 70 e(String tag, String msg, Exception e)71 public static void e(String tag, String msg, Exception e) { 72 android.util.Log.e(TAG, delimit(tag) + msg, e); 73 } 74 e(String tag, String msg)75 public static void e(String tag, String msg) { 76 android.util.Log.e(TAG, delimit(tag) + msg); 77 } 78 e(Object obj, String msg, Exception e)79 public static void e(Object obj, String msg, Exception e) { 80 android.util.Log.e(TAG, getPrefix(obj) + msg, e); 81 } 82 e(Object obj, String msg)83 public static void e(Object obj, String msg) { 84 android.util.Log.e(TAG, getPrefix(obj) + msg); 85 } 86 i(String tag, String msg)87 public static void i(String tag, String msg) { 88 android.util.Log.i(TAG, delimit(tag) + msg); 89 } 90 i(Object obj, String msg)91 public static void i(Object obj, String msg) { 92 android.util.Log.i(TAG, getPrefix(obj) + msg); 93 } 94 w(Object obj, String msg)95 public static void w(Object obj, String msg) { 96 android.util.Log.w(TAG, getPrefix(obj) + msg); 97 } 98 wtf(Object obj, String msg)99 public static void wtf(Object obj, String msg) { 100 android.util.Log.wtf(TAG, getPrefix(obj) + msg); 101 } 102 piiHandle(Object pii)103 public static String piiHandle(Object pii) { 104 if (pii == null || VERBOSE) { 105 return String.valueOf(pii); 106 } 107 108 if (pii instanceof Uri) { 109 Uri uri = (Uri) pii; 110 111 // All Uri's which are not "tel" go through normal pii() method. 112 if (!PhoneAccount.SCHEME_TEL.equals(uri.getScheme())) { 113 return pii(pii); 114 } else { 115 pii = uri.getSchemeSpecificPart(); 116 } 117 } 118 119 String originalString = String.valueOf(pii); 120 StringBuilder stringBuilder = new StringBuilder(originalString.length()); 121 for (char c : originalString.toCharArray()) { 122 if (PhoneNumberUtils.isDialable(c)) { 123 stringBuilder.append('*'); 124 } else { 125 stringBuilder.append(c); 126 } 127 } 128 return stringBuilder.toString(); 129 } 130 131 /** 132 * Redact personally identifiable information for production users. 133 * If we are running in verbose mode, return the original string, otherwise 134 * return a SHA-1 hash of the input string. 135 */ pii(Object pii)136 public static String pii(Object pii) { 137 if (pii == null || VERBOSE) { 138 return String.valueOf(pii); 139 } 140 return "[" + secureHash(String.valueOf(pii).getBytes()) + "]"; 141 } 142 secureHash(byte[] input)143 private static String secureHash(byte[] input) { 144 MessageDigest messageDigest; 145 try { 146 messageDigest = MessageDigest.getInstance("SHA-1"); 147 } catch (NoSuchAlgorithmException e) { 148 return null; 149 } 150 messageDigest.update(input); 151 byte[] result = messageDigest.digest(); 152 return encodeHex(result); 153 } 154 encodeHex(byte[] bytes)155 private static String encodeHex(byte[] bytes) { 156 StringBuffer hex = new StringBuffer(bytes.length * 2); 157 158 for (int i = 0; i < bytes.length; i++) { 159 int byteIntValue = bytes[i] & 0xff; 160 if (byteIntValue < 0x10) { 161 hex.append("0"); 162 } 163 hex.append(Integer.toString(byteIntValue, 16)); 164 } 165 166 return hex.toString(); 167 } 168 getPrefix(Object obj)169 private static String getPrefix(Object obj) { 170 return (obj == null ? "" : (obj.getClass().getSimpleName() + TAG_DELIMETER)); 171 } 172 delimit(String tag)173 private static String delimit(String tag) { 174 return tag + TAG_DELIMETER; 175 } 176 } 177