Home | History | Annotate | Download | only in telecom
      1 /*
      2  * Copyright 2014, 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 android.telecom;
     18 
     19 import java.security.MessageDigest;
     20 import java.security.NoSuchAlgorithmException;
     21 import java.util.IllegalFormatException;
     22 import java.util.Locale;
     23 
     24 /**
     25  * Manages logging for the entire module.
     26  *
     27  * @hide
     28  */
     29 final public class Log {
     30 
     31     // Generic tag for all Telecom Framework logging
     32     private static final String TAG = "TelecomFramework";
     33 
     34     public static final boolean FORCE_LOGGING = false; /* STOP SHIP if true */
     35     public static final boolean DEBUG = isLoggable(android.util.Log.DEBUG);
     36     public static final boolean INFO = isLoggable(android.util.Log.INFO);
     37     public static final boolean VERBOSE = isLoggable(android.util.Log.VERBOSE);
     38     public static final boolean WARN = isLoggable(android.util.Log.WARN);
     39     public static final boolean ERROR = isLoggable(android.util.Log.ERROR);
     40 
     41     private Log() {}
     42 
     43     public static boolean isLoggable(int level) {
     44         return FORCE_LOGGING || android.util.Log.isLoggable(TAG, level);
     45     }
     46 
     47     public static void d(String prefix, String format, Object... args) {
     48         if (DEBUG) {
     49             android.util.Log.d(TAG, buildMessage(prefix, format, args));
     50         }
     51     }
     52 
     53     public static void d(Object objectPrefix, String format, Object... args) {
     54         if (DEBUG) {
     55             android.util.Log.d(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
     56         }
     57     }
     58 
     59     public static void i(String prefix, String format, Object... args) {
     60         if (INFO) {
     61             android.util.Log.i(TAG, buildMessage(prefix, format, args));
     62         }
     63     }
     64 
     65     public static void i(Object objectPrefix, String format, Object... args) {
     66         if (INFO) {
     67             android.util.Log.i(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
     68         }
     69     }
     70 
     71     public static void v(String prefix, String format, Object... args) {
     72         if (VERBOSE) {
     73             android.util.Log.v(TAG, buildMessage(prefix, format, args));
     74         }
     75     }
     76 
     77     public static void v(Object objectPrefix, String format, Object... args) {
     78         if (VERBOSE) {
     79             android.util.Log.v(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
     80         }
     81     }
     82 
     83     public static void w(String prefix, String format, Object... args) {
     84         if (WARN) {
     85             android.util.Log.w(TAG, buildMessage(prefix, format, args));
     86         }
     87     }
     88 
     89     public static void w(Object objectPrefix, String format, Object... args) {
     90         if (WARN) {
     91             android.util.Log.w(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
     92         }
     93     }
     94 
     95     public static void e(String prefix, Throwable tr, String format, Object... args) {
     96         if (ERROR) {
     97             android.util.Log.e(TAG, buildMessage(prefix, format, args), tr);
     98         }
     99     }
    100 
    101     public static void e(Object objectPrefix, Throwable tr, String format, Object... args) {
    102         if (ERROR) {
    103             android.util.Log.e(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args),
    104                     tr);
    105         }
    106     }
    107 
    108     public static void wtf(String prefix, Throwable tr, String format, Object... args) {
    109         android.util.Log.wtf(TAG, buildMessage(prefix, format, args), tr);
    110     }
    111 
    112     public static void wtf(Object objectPrefix, Throwable tr, String format, Object... args) {
    113         android.util.Log.wtf(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args),
    114                 tr);
    115     }
    116 
    117     public static void wtf(String prefix, String format, Object... args) {
    118         String msg = buildMessage(prefix, format, args);
    119         android.util.Log.wtf(TAG, msg, new IllegalStateException(msg));
    120     }
    121 
    122     public static void wtf(Object objectPrefix, String format, Object... args) {
    123         String msg = buildMessage(getPrefixFromObject(objectPrefix), format, args);
    124         android.util.Log.wtf(TAG, msg, new IllegalStateException(msg));
    125     }
    126 
    127     /**
    128      * Redact personally identifiable information for production users.
    129      * If we are running in verbose mode, return the original string, otherwise
    130      * return a SHA-1 hash of the input string.
    131      */
    132     public static String pii(Object pii) {
    133         if (pii == null || VERBOSE) {
    134             return String.valueOf(pii);
    135         }
    136         return "[" + secureHash(String.valueOf(pii).getBytes()) + "]";
    137     }
    138 
    139     private static String secureHash(byte[] input) {
    140         MessageDigest messageDigest;
    141         try {
    142             messageDigest = MessageDigest.getInstance("SHA-1");
    143         } catch (NoSuchAlgorithmException e) {
    144             return null;
    145         }
    146         messageDigest.update(input);
    147         byte[] result = messageDigest.digest();
    148         return encodeHex(result);
    149     }
    150 
    151     private static String encodeHex(byte[] bytes) {
    152         StringBuffer hex = new StringBuffer(bytes.length * 2);
    153 
    154         for (int i = 0; i < bytes.length; i++) {
    155             int byteIntValue = bytes[i] & 0xff;
    156             if (byteIntValue < 0x10) {
    157                 hex.append("0");
    158             }
    159             hex.append(Integer.toString(byteIntValue, 16));
    160         }
    161 
    162         return hex.toString();
    163     }
    164 
    165     private static String getPrefixFromObject(Object obj) {
    166         return obj == null ? "<null>" : obj.getClass().getSimpleName();
    167     }
    168 
    169     private static String buildMessage(String prefix, String format, Object... args) {
    170         String msg;
    171         try {
    172             msg = (args == null || args.length == 0) ? format
    173                     : String.format(Locale.US, format, args);
    174         } catch (IllegalFormatException ife) {
    175             wtf("Log", ife, "IllegalFormatException: formatString='%s' numArgs=%d", format,
    176                     args.length);
    177             msg = format + " (An error occurred while formatting the message.)";
    178         }
    179         return String.format(Locale.US, "%s: %s", prefix, msg);
    180     }
    181 }
    182