14822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal/*
24822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal * Copyright 2014, The Android Open Source Project
34822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal *
44822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal * Licensed under the Apache License, Version 2.0 (the "License");
54822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal * you may not use this file except in compliance with the License.
64822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal * You may obtain a copy of the License at
74822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal *
84822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal *     http://www.apache.org/licenses/LICENSE-2.0
94822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal *
104822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal * Unless required by applicable law or agreed to in writing, software
114822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal * distributed under the License is distributed on an "AS IS" BASIS,
124822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal * See the License for the specific language governing permissions and
144822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal * limitations under the License.
154822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal */
164822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
174822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepalpackage com.android.services.telephony;
184822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
194822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepalimport java.security.MessageDigest;
204822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepalimport java.security.NoSuchAlgorithmException;
214822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepalimport java.util.IllegalFormatException;
224822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepalimport java.util.Locale;
234822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
244822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal/**
254822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal * Manages logging for the entire module.
264822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal */
274822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepalfinal public class Log {
284822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
294822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    // Generic tag for all In Call logging
304822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    private static final String TAG = "Telephony";
314822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
32ddb96cef8136a6e047c3f35cc5198456b36aee0dSantos Cordon    public static final boolean FORCE_LOGGING = false; /* STOP SHIP if true */
334822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static final boolean DEBUG = isLoggable(android.util.Log.DEBUG);
344822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static final boolean INFO = isLoggable(android.util.Log.INFO);
354822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static final boolean VERBOSE = isLoggable(android.util.Log.VERBOSE);
364822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static final boolean WARN = isLoggable(android.util.Log.WARN);
374822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static final boolean ERROR = isLoggable(android.util.Log.ERROR);
384822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
394822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    private Log() {}
404822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
414822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static boolean isLoggable(int level) {
424822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        return FORCE_LOGGING || android.util.Log.isLoggable(TAG, level);
434822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
444822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
454822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void d(String prefix, String format, Object... args) {
464822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        if (DEBUG) {
474822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            android.util.Log.d(TAG, buildMessage(prefix, format, args));
484822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
494822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
504822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
514822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void d(Object objectPrefix, String format, Object... args) {
524822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        if (DEBUG) {
534822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            android.util.Log.d(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
544822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
554822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
564822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
574822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void i(String prefix, String format, Object... args) {
584822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        if (INFO) {
594822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            android.util.Log.i(TAG, buildMessage(prefix, format, args));
604822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
614822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
624822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
634822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void i(Object objectPrefix, String format, Object... args) {
644822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        if (INFO) {
654822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            android.util.Log.i(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
664822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
674822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
684822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
694822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void v(String prefix, String format, Object... args) {
704822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        if (VERBOSE) {
714822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            android.util.Log.v(TAG, buildMessage(prefix, format, args));
724822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
734822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
744822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
754822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void v(Object objectPrefix, String format, Object... args) {
764822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        if (VERBOSE) {
774822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            android.util.Log.v(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
784822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
794822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
804822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
814822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void w(String prefix, String format, Object... args) {
824822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        if (WARN) {
834822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            android.util.Log.w(TAG, buildMessage(prefix, format, args));
844822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
854822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
864822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
874822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void w(Object objectPrefix, String format, Object... args) {
884822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        if (WARN) {
894822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            android.util.Log.w(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
904822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
914822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
924822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
934822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void e(String prefix, Throwable tr, String format, Object... args) {
944822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        if (ERROR) {
954822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            android.util.Log.e(TAG, buildMessage(prefix, format, args), tr);
964822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
974822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
984822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
994822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void e(Object objectPrefix, Throwable tr, String format, Object... args) {
1004822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        if (ERROR) {
1014822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            android.util.Log.e(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args),
1024822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal                    tr);
1034822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
1044822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
1054822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
1064822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void wtf(String prefix, Throwable tr, String format, Object... args) {
1074822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        android.util.Log.wtf(TAG, buildMessage(prefix, format, args), tr);
1084822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
1094822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
1104822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void wtf(Object objectPrefix, Throwable tr, String format, Object... args) {
1114822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        android.util.Log.wtf(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args),
1124822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal                tr);
1134822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
1144822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
1154822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void wtf(String prefix, String format, Object... args) {
1164822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        String msg = buildMessage(prefix, format, args);
1174822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        android.util.Log.wtf(TAG, msg, new IllegalStateException(msg));
1184822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
1194822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
1204822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static void wtf(Object objectPrefix, String format, Object... args) {
1214822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        String msg = buildMessage(getPrefixFromObject(objectPrefix), format, args);
1224822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        android.util.Log.wtf(TAG, msg, new IllegalStateException(msg));
1234822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
1244822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
1254822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    /**
1264822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal     * Redact personally identifiable information for production users.
1274822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal     * If we are running in verbose mode, return the original string, otherwise
1284822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal     * return a SHA-1 hash of the input string.
1294822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal     */
1304822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    public static String pii(Object pii) {
1314822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        if (pii == null || VERBOSE) {
1324822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            return String.valueOf(pii);
1334822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
1344822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        return "[" + secureHash(String.valueOf(pii).getBytes()) + "]";
1354822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
1364822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
1374822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    private static String secureHash(byte[] input) {
1384822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        MessageDigest messageDigest;
1394822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        try {
1404822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            messageDigest = MessageDigest.getInstance("SHA-1");
1414822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        } catch (NoSuchAlgorithmException e) {
1424822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            return null;
1434822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
1444822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        messageDigest.update(input);
1454822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        byte[] result = messageDigest.digest();
1464822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        return encodeHex(result);
1474822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
1484822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
1494822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    private static String encodeHex(byte[] bytes) {
1504822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        StringBuffer hex = new StringBuffer(bytes.length * 2);
1514822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
1524822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        for (int i = 0; i < bytes.length; i++) {
1534822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            int byteIntValue = bytes[i] & 0xff;
1544822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            if (byteIntValue < 0x10) {
1554822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal                hex.append("0");
1564822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            }
1574822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            hex.append(Integer.toString(byteIntValue, 16));
1584822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
1594822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
1604822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        return hex.toString();
1614822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
1624822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
1634822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    private static String getPrefixFromObject(Object obj) {
1644822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        return obj == null ? "<null>" : obj.getClass().getSimpleName();
1654822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
1664822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal
1674822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    private static String buildMessage(String prefix, String format, Object... args) {
1684822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        String msg;
1694822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        try {
1704822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            msg = (args == null || args.length == 0) ? format
1714822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal                    : String.format(Locale.US, format, args);
1724822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        } catch (IllegalFormatException ife) {
1734822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            wtf("Log", ife, "IllegalFormatException: formatString='%s' numArgs=%d", format,
1744822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal                    args.length);
1754822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal            msg = format + " (An error occurred while formatting the message.)";
1764822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        }
1774822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal        return String.format(Locale.US, "%s: %s", prefix, msg);
1784822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal    }
1794822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal}
180