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