17b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira/**
27b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * Copyright (c) 2011, Google Inc.
37b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira *
47b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * Licensed under the Apache License, Version 2.0 (the "License");
57b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * you may not use this file except in compliance with the License.
67b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * You may obtain a copy of the License at
77b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira *
87b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira *     http://www.apache.org/licenses/LICENSE-2.0
97b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira *
107b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * Unless required by applicable law or agreed to in writing, software
117b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS,
127b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * See the License for the specific language governing permissions and
147b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * limitations under the License.
157b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira */
1630e2c24b056542f3b1b438aeb798305d1226d0c8Andy Huangpackage com.android.mail.utils;
177b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
187b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereiraimport android.net.Uri;
19116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereiraimport android.text.TextUtils;
207b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereiraimport android.util.Log;
2132fc8e41dde99760eb769a0d0c17f6c485a0b5cfScott Kennedy
227b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereiraimport com.google.common.annotations.VisibleForTesting;
237b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
247b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereiraimport java.util.List;
25116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereiraimport java.util.regex.Pattern;
267b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
277b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereirapublic class LogUtils {
28116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira
29b184bfe96fa3512af88260fce4f3cee3066fb28dScott Kennedy    public static final String TAG = LogTag.getLogTag();
30a6c0cb31769f34b7b033167893026f1be2e9baa3Marc Blank
31116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira    // "GMT" + "+" or "-" + 4 digits
32116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira    private static final Pattern DATE_CLEANUP_PATTERN_WRONG_TIMEZONE =
33116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira            Pattern.compile("GMT([-+]\\d{4})$");
347b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
3519ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook    private static final String ACCOUNT_PREFIX = "account:";
3619ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook
377b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
387b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Priority constant for the println method; use LogUtils.v.
397b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
407b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static final int VERBOSE = Log.VERBOSE;
417b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
427b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
437b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Priority constant for the println method; use LogUtils.d.
447b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
457b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static final int DEBUG = Log.DEBUG;
467b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
477b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
487b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Priority constant for the println method; use LogUtils.i.
497b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
507b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static final int INFO = Log.INFO;
517b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
527b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
537b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Priority constant for the println method; use LogUtils.w.
547b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
557b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static final int WARN = Log.WARN;
567b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
577b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
587b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Priority constant for the println method; use LogUtils.e.
597b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
607b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static final int ERROR = Log.ERROR;
617b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
627b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
637b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Used to enable/disable logging that we don't want included in
64c6952fcb8474af1b7197088b7df9a676f127c663Alice Yang     * production releases.  This should be set to DEBUG for production releases, and VERBOSE for
65c6952fcb8474af1b7197088b7df9a676f127c663Alice Yang     * internal builds.
667b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
6787f5b7aa888b8fa42636a90346c1223dcc7bb023Andy Huang    // STOPSHIP: ship with DEBUG set
6887f5b7aa888b8fa42636a90346c1223dcc7bb023Andy Huang    private static final int MAX_ENABLED_LOG_LEVEL = VERBOSE;
697b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
707b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    private static Boolean sDebugLoggingEnabledForTests = null;
717b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
727b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
737b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Enable debug logging for unit tests.
747b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
757b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    @VisibleForTesting
76b184bfe96fa3512af88260fce4f3cee3066fb28dScott Kennedy    public static void setDebugLoggingEnabledForTests(boolean enabled) {
7728e1b9efb3914d67ba2a050681ab666b8ac9beb8Paul Westbrook        setDebugLoggingEnabledForTestsInternal(enabled);
7828e1b9efb3914d67ba2a050681ab666b8ac9beb8Paul Westbrook    }
7928e1b9efb3914d67ba2a050681ab666b8ac9beb8Paul Westbrook
8028e1b9efb3914d67ba2a050681ab666b8ac9beb8Paul Westbrook    protected static void setDebugLoggingEnabledForTestsInternal(boolean enabled) {
817b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        sDebugLoggingEnabledForTests = Boolean.valueOf(enabled);
827b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
837b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
847b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
857b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Returns true if the build configuration prevents debug logging.
867b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
877b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    @VisibleForTesting
884f0eaec8f7b56ff484c46b2ac33d141e7685a386Paul Westbrook    public static boolean buildPreventsDebugLogging() {
897b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        return MAX_ENABLED_LOG_LEVEL > VERBOSE;
907b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
917b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
927b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
937b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Returns a boolean indicating whether debug logging is enabled.
947b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
95b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook    protected static boolean isDebugLoggingEnabled(String tag) {
967b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (buildPreventsDebugLogging()) {
977b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return false;
987b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
997b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (sDebugLoggingEnabledForTests != null) {
1007b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return sDebugLoggingEnabledForTests.booleanValue();
1017b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
102b184bfe96fa3512af88260fce4f3cee3066fb28dScott Kennedy        return Log.isLoggable(tag, Log.DEBUG) || Log.isLoggable(TAG, Log.DEBUG);
103b184bfe96fa3512af88260fce4f3cee3066fb28dScott Kennedy    }
104b184bfe96fa3512af88260fce4f3cee3066fb28dScott Kennedy
105b184bfe96fa3512af88260fce4f3cee3066fb28dScott Kennedy    /**
106b184bfe96fa3512af88260fce4f3cee3066fb28dScott Kennedy     * Returns a String for the specified content provider uri.  This will do
107b184bfe96fa3512af88260fce4f3cee3066fb28dScott Kennedy     * sanitation of the uri to remove PII if debug logging is not enabled.
108b184bfe96fa3512af88260fce4f3cee3066fb28dScott Kennedy     */
109b184bfe96fa3512af88260fce4f3cee3066fb28dScott Kennedy    public static String contentUriToString(final Uri uri) {
110b184bfe96fa3512af88260fce4f3cee3066fb28dScott Kennedy        return contentUriToString(TAG, uri);
1117b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
1127b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
1137b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
1147b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Returns a String for the specified content provider uri.  This will do
1157b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * sanitation of the uri to remove PII if debug logging is not enabled.
1167b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
117b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook    public static String contentUriToString(String tag, Uri uri) {
118b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook        if (isDebugLoggingEnabled(tag)) {
1197b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            // Debug logging has been enabled, so log the uri as is
1207b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return uri.toString();
1217b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        } else {
1227b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            // Debug logging is not enabled, we want to remove the email address from the uri.
1237b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            List<String> pathSegments = uri.getPathSegments();
1247b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
1257b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            Uri.Builder builder = new Uri.Builder()
1267b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira                    .scheme(uri.getScheme())
1277b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira                    .authority(uri.getAuthority())
1287b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira                    .query(uri.getQuery())
1297b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira                    .fragment(uri.getFragment());
1307b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
1317b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            // This assumes that the first path segment is the account
1327b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            final String account = pathSegments.get(0);
1337b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
13419ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook            builder = builder.appendPath(sanitizeAccountName(account));
1357b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            for (int i = 1; i < pathSegments.size(); i++) {
1367b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira                builder.appendPath(pathSegments.get(i));
1377b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            }
1387b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return builder.toString();
1397b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
1407b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
1417b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
1427b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
14319ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook     * Sanitizes an account name.  If debug logging is not enabled, a sanitized name
14419ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook     * is returned.
14519ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook     */
14619ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook    public static String sanitizeAccountName(String accountName) {
14719ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook        if (TextUtils.isEmpty(accountName)) {
14819ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook            return "";
14919ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook        }
15019ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook
15132fc8e41dde99760eb769a0d0c17f6c485a0b5cfScott Kennedy        return ACCOUNT_PREFIX + sanitizeName(TAG, accountName);
15232fc8e41dde99760eb769a0d0c17f6c485a0b5cfScott Kennedy    }
15332fc8e41dde99760eb769a0d0c17f6c485a0b5cfScott Kennedy
15432fc8e41dde99760eb769a0d0c17f6c485a0b5cfScott Kennedy    public static String sanitizeName(final String tag, final String name) {
15532fc8e41dde99760eb769a0d0c17f6c485a0b5cfScott Kennedy        if (TextUtils.isEmpty(name)) {
15632fc8e41dde99760eb769a0d0c17f6c485a0b5cfScott Kennedy            return "";
15732fc8e41dde99760eb769a0d0c17f6c485a0b5cfScott Kennedy        }
15832fc8e41dde99760eb769a0d0c17f6c485a0b5cfScott Kennedy
15932fc8e41dde99760eb769a0d0c17f6c485a0b5cfScott Kennedy        if (isDebugLoggingEnabled(tag)) {
16032fc8e41dde99760eb769a0d0c17f6c485a0b5cfScott Kennedy            return name;
16119ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook        }
16219ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook
16332fc8e41dde99760eb769a0d0c17f6c485a0b5cfScott Kennedy        return String.valueOf(name.hashCode());
16419ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook    }
16519ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook
16619ea5680e54b14f364ac860333992a29ca5acdb9Paul Westbrook    /**
1677b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Checks to see whether or not a log for the specified tag is loggable at the specified level.
1687b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
1697b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static boolean isLoggable(String tag, int level) {
1707b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (MAX_ENABLED_LOG_LEVEL > level) {
1717b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return false;
1727b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
173b184bfe96fa3512af88260fce4f3cee3066fb28dScott Kennedy        return Log.isLoggable(tag, level) || Log.isLoggable(TAG, level);
1747b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
1757b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
1767b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
1777b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Send a {@link #VERBOSE} log message.
1787b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tag Used to identify the source of a log message.  It usually identifies
1797b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *        the class or activity where the log call occurs.
1807b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param format the format string (see {@link java.util.Formatter#format})
1817b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param args
1827b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            the list of arguments passed to the formatter. If there are
1837b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            more arguments than required by {@code format},
1847b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            additional arguments are ignored.
1857b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
1867b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static int v(String tag, String format, Object... args) {
1877b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (isLoggable(tag, VERBOSE)) {
1887b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return Log.v(tag, String.format(format, args));
1897b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
1907b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        return 0;
1917b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
1927b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
1937b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
1947b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Send a {@link #VERBOSE} log message.
1957b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tag Used to identify the source of a log message.  It usually identifies
1967b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *        the class or activity where the log call occurs.
1977b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tr An exception to log
1987b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param format the format string (see {@link java.util.Formatter#format})
1997b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param args
2007b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            the list of arguments passed to the formatter. If there are
2017b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            more arguments than required by {@code format},
2027b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            additional arguments are ignored.
2037b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
2047b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static int v(String tag, Throwable tr, String format, Object... args) {
2057b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (isLoggable(tag, VERBOSE)) {
2067b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return Log.v(tag, String.format(format, args), tr);
2077b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
2087b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        return 0;
2097b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
2107b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
2117b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
2127b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Send a {@link #DEBUG} log message.
2137b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tag Used to identify the source of a log message.  It usually identifies
2147b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *        the class or activity where the log call occurs.
2157b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param format the format string (see {@link java.util.Formatter#format})
2167b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param args
2177b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            the list of arguments passed to the formatter. If there are
2187b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            more arguments than required by {@code format},
2197b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            additional arguments are ignored.
2207b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
2217b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static int d(String tag, String format, Object... args) {
2227b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (isLoggable(tag, DEBUG)) {
2237b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return Log.d(tag, String.format(format, args));
2247b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
2257b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        return 0;
2267b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
2277b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
2287b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
2297b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Send a {@link #DEBUG} log message.
2307b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tag Used to identify the source of a log message.  It usually identifies
2317b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *        the class or activity where the log call occurs.
2327b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tr An exception to log
2337b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param format the format string (see {@link java.util.Formatter#format})
2347b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param args
2357b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            the list of arguments passed to the formatter. If there are
2367b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            more arguments than required by {@code format},
2377b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            additional arguments are ignored.
2387b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
2397b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static int d(String tag, Throwable tr, String format, Object... args) {
2407b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (isLoggable(tag, DEBUG)) {
2417b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return Log.d(tag, String.format(format, args), tr);
2427b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
2437b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        return 0;
2447b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
2457b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
2467b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
2477b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Send a {@link #INFO} log message.
2487b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tag Used to identify the source of a log message.  It usually identifies
2497b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *        the class or activity where the log call occurs.
2507b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param format the format string (see {@link java.util.Formatter#format})
2517b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param args
2527b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            the list of arguments passed to the formatter. If there are
2537b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            more arguments than required by {@code format},
2547b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            additional arguments are ignored.
2557b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
2567b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static int i(String tag, String format, Object... args) {
2577b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (isLoggable(tag, INFO)) {
2587b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return Log.i(tag, String.format(format, args));
2597b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
2607b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        return 0;
2617b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
2627b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
2637b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
2647b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Send a {@link #INFO} log message.
2657b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tag Used to identify the source of a log message.  It usually identifies
2667b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *        the class or activity where the log call occurs.
2677b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tr An exception to log
2687b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param format the format string (see {@link java.util.Formatter#format})
2697b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param args
2707b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            the list of arguments passed to the formatter. If there are
2717b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            more arguments than required by {@code format},
2727b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            additional arguments are ignored.
2737b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
2747b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static int i(String tag, Throwable tr, String format, Object... args) {
2757b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (isLoggable(tag, INFO)) {
2767b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return Log.i(tag, String.format(format, args), tr);
2777b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
2787b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        return 0;
2797b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
2807b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
2817b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
2827b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Send a {@link #WARN} log message.
2837b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tag Used to identify the source of a log message.  It usually identifies
2847b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *        the class or activity where the log call occurs.
2857b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param format the format string (see {@link java.util.Formatter#format})
2867b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param args
2877b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            the list of arguments passed to the formatter. If there are
2887b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            more arguments than required by {@code format},
2897b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            additional arguments are ignored.
2907b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
2917b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static int w(String tag, String format, Object... args) {
2927b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (isLoggable(tag, WARN)) {
2937b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return Log.w(tag, String.format(format, args));
2947b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
2957b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        return 0;
2967b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
2977b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
2987b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
2997b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Send a {@link #WARN} log message.
3007b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tag Used to identify the source of a log message.  It usually identifies
3017b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *        the class or activity where the log call occurs.
3027b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tr An exception to log
3037b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param format the format string (see {@link java.util.Formatter#format})
3047b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param args
3057b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            the list of arguments passed to the formatter. If there are
3067b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            more arguments than required by {@code format},
3077b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            additional arguments are ignored.
3087b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
3097b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static int w(String tag, Throwable tr, String format, Object... args) {
3107b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (isLoggable(tag, WARN)) {
3117b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return Log.w(tag, String.format(format, args), tr);
3127b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
3137b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        return 0;
3147b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
3157b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
3167b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
3177b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Send a {@link #ERROR} log message.
3187b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tag Used to identify the source of a log message.  It usually identifies
3197b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *        the class or activity where the log call occurs.
3207b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param format the format string (see {@link java.util.Formatter#format})
3217b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param args
3227b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            the list of arguments passed to the formatter. If there are
3237b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            more arguments than required by {@code format},
3247b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            additional arguments are ignored.
3257b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
3267b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static int e(String tag, String format, Object... args) {
3277b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (isLoggable(tag, ERROR)) {
3287b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return Log.e(tag, String.format(format, args));
3297b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
3307b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        return 0;
3317b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
3327b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
3337b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
3347b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Send a {@link #ERROR} log message.
3357b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tag Used to identify the source of a log message.  It usually identifies
3367b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *        the class or activity where the log call occurs.
3377b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tr An exception to log
3387b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param format the format string (see {@link java.util.Formatter#format})
3397b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param args
3407b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            the list of arguments passed to the formatter. If there are
3417b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            more arguments than required by {@code format},
3427b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            additional arguments are ignored.
3437b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
3447b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static int e(String tag, Throwable tr, String format, Object... args) {
3457b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        if (isLoggable(tag, ERROR)) {
3467b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira            return Log.e(tag, String.format(format, args), tr);
3477b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        }
3487b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        return 0;
3497b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
3507b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
3517b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
3527b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * What a Terrible Failure: Report a condition that should never happen.
3537b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * The error will always be logged at level ASSERT with the call stack.
3547b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Depending on system configuration, a report may be added to the
3557b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * {@link android.os.DropBoxManager} and/or the process may be terminated
3567b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * immediately with an error dialog.
3577b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tag Used to identify the source of a log message.  It usually identifies
3587b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *        the class or activity where the log call occurs.
3597b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param format the format string (see {@link java.util.Formatter#format})
3607b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param args
3617b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            the list of arguments passed to the formatter. If there are
3627b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            more arguments than required by {@code format},
3637b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            additional arguments are ignored.
3647b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
3657b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static int wtf(String tag, String format, Object... args) {
366a916191f6b6920e3c442ecb4bc61c9bf27b40f00Paul Westbrook        return Log.wtf(tag, String.format(format, args), new Error());
3677b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
3687b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira
3697b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    /**
3707b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * What a Terrible Failure: Report a condition that should never happen.
3717b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * The error will always be logged at level ASSERT with the call stack.
3727b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * Depending on system configuration, a report may be added to the
3737b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * {@link android.os.DropBoxManager} and/or the process may be terminated
3747b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * immediately with an error dialog.
3757b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tag Used to identify the source of a log message.  It usually identifies
3767b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *        the class or activity where the log call occurs.
3777b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param tr An exception to log
3787b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param format the format string (see {@link java.util.Formatter#format})
3797b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     * @param args
3807b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            the list of arguments passed to the formatter. If there are
3817b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            more arguments than required by {@code format},
3827b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     *            additional arguments are ignored.
3837b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira     */
3847b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    public static int wtf(String tag, Throwable tr, String format, Object... args) {
3857b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira        return Log.wtf(tag, String.format(format, args), tr);
3867b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira    }
387116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira
388116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira
389116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira    /**
390116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira     * Try to make a date MIME(RFC 2822/5322)-compliant.
391116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira     *
392116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira     * It fixes:
393116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira     * - "Thu, 10 Dec 09 15:08:08 GMT-0700" to "Thu, 10 Dec 09 15:08:08 -0700"
394116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira     *   (4 digit zone value can't be preceded by "GMT")
395116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira     *   We got a report saying eBay sends a date in this format
396116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira     */
397116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira    public static String cleanUpMimeDate(String date) {
398116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira        if (TextUtils.isEmpty(date)) {
399116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira            return date;
400116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira        }
401116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira        date = DATE_CLEANUP_PATTERN_WRONG_TIMEZONE.matcher(date).replaceFirst("$1");
402116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira        return date;
403116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira    }
404116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira
405116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira
406116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira    public static String byteToHex(int b) {
407116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira        return byteToHex(new StringBuilder(), b).toString();
408116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira    }
409116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira
410116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira    public static StringBuilder byteToHex(StringBuilder sb, int b) {
411116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira        b &= 0xFF;
412116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira        sb.append("0123456789ABCDEF".charAt(b >> 4));
413116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira        sb.append("0123456789ABCDEF".charAt(b & 0xF));
414116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira        return sb;
415116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira    }
416116e09e6f5aef14fb6cc51a7496ea27490e18d20Mindy Pereira
4177b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira}
418