155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project/*
255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project *
455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * you may not use this file except in compliance with the License.
655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * You may obtain a copy of the License at
755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project *
855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project *
1055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * See the License for the specific language governing permissions and
1455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * limitations under the License.
1555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */
1655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
1755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectpackage com.android.ddmlib;
1855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
1955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport java.io.PrintWriter;
2055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport java.io.StringWriter;
21e551cd75cfbbdd4ab4040b7d5c290a715e944305Brett Chabotimport java.text.SimpleDateFormat;
22e551cd75cfbbdd4ab4040b7d5c290a715e944305Brett Chabotimport java.util.Date;
2355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
2455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project/**
2555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Log class that mirrors the API in main Android sources.
2655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * <p/>Default behavior outputs the log to {@link System#out}. Use
2755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * {@link #setLogOutput(com.android.ddmlib.Log.ILogOutput)} to redirect the log somewhere else.
2855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */
2955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectpublic final class Log {
3055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
3155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
3255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Log Level enum.
3355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
3455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public enum LogLevel {
3555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        VERBOSE(2, "verbose", 'V'), //$NON-NLS-1$
3655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        DEBUG(3, "debug", 'D'), //$NON-NLS-1$
3755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        INFO(4, "info", 'I'), //$NON-NLS-1$
3855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        WARN(5, "warn", 'W'), //$NON-NLS-1$
3955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        ERROR(6, "error", 'E'), //$NON-NLS-1$
4055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        ASSERT(7, "assert", 'A'); //$NON-NLS-1$
4155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
4255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        private int mPriorityLevel;
4355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        private String mStringValue;
4455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        private char mPriorityLetter;
4555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
4655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        LogLevel(int intPriority, String stringValue, char priorityChar) {
4755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            mPriorityLevel = intPriority;
4855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            mStringValue = stringValue;
4955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            mPriorityLetter = priorityChar;
5055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
5155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
5255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        public static LogLevel getByString(String value) {
5355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            for (LogLevel mode : values()) {
5455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                if (mode.mStringValue.equals(value)) {
5555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                    return mode;
5655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                }
5755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            }
5855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
5955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            return null;
6055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
6155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
6255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        /**
6355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * Returns the {@link LogLevel} enum matching the specified letter.
6455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * @param letter the letter matching a <code>LogLevel</code> enum
6555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * @return a <code>LogLevel</code> object or <code>null</code> if no match were found.
6655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         */
6755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        public static LogLevel getByLetter(char letter) {
6855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            for (LogLevel mode : values()) {
6955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                if (mode.mPriorityLetter == letter) {
7055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                    return mode;
7155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                }
7255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            }
7355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
7455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            return null;
7555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
7655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
7755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        /**
7855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * Returns the {@link LogLevel} enum matching the specified letter.
7955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * <p/>
8055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * The letter is passed as a {@link String} argument, but only the first character
8155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * is used.
8255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * @param letter the letter matching a <code>LogLevel</code> enum
8355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * @return a <code>LogLevel</code> object or <code>null</code> if no match were found.
8455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         */
8555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        public static LogLevel getByLetterString(String letter) {
8655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            if (letter.length() > 0) {
8755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                return getByLetter(letter.charAt(0));
8855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            }
8955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
9055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            return null;
9155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
9255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
9355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        /**
9455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * Returns the letter identifying the priority of the {@link LogLevel}.
9555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         */
9655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        public char getPriorityLetter() {
9755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            return mPriorityLetter;
9855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
9955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
10055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        /**
10155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * Returns the numerical value of the priority.
10255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         */
10355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        public int getPriority() {
10455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            return mPriorityLevel;
10555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
10655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
10755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        /**
10855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * Returns a non translated string representing the LogLevel.
10955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         */
11055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        public String getStringValue() {
11155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            return mStringValue;
11255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
11355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
11455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
11555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
11655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Classes which implement this interface provides methods that deal with outputting log
11755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * messages.
11855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
11955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public interface ILogOutput {
12055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        /**
12155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * Sent when a log message needs to be printed.
12255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * @param logLevel The {@link LogLevel} enum representing the priority of the message.
12355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * @param tag The tag associated with the message.
12455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * @param message The message to display.
12555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         */
12655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        public void printLog(LogLevel logLevel, String tag, String message);
12755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
12855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        /**
12955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * Sent when a log message needs to be printed, and, if possible, displayed to the user
13055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * in a dialog box.
13155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * @param logLevel The {@link LogLevel} enum representing the priority of the message.
13255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * @param tag The tag associated with the message.
13355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         * @param message The message to display.
13455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project         */
13555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        public void printAndPromptLog(LogLevel logLevel, String tag, String message);
13655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
13755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
13855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    private static LogLevel mLevel = DdmPreferences.getLogLevel();
13955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
14055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    private static ILogOutput sLogOutput;
14155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
14255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    private static final char[] mSpaceLine = new char[72];
14355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    private static final char[] mHexDigit = new char[]
14455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
14555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    static {
14655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        /* prep for hex dump */
14755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        int i = mSpaceLine.length-1;
14855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        while (i >= 0)
14955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            mSpaceLine[i--] = ' ';
15055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        mSpaceLine[0] = mSpaceLine[1] = mSpaceLine[2] = mSpaceLine[3] = '0';
15155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        mSpaceLine[4] = '-';
15255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
15355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
15455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    static final class Config {
15555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        static final boolean LOGV = true;
15655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        static final boolean LOGD = true;
15755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    };
15855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
15955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    private Log() {}
16055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
16155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
16255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Outputs a {@link LogLevel#VERBOSE} level message.
16355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param tag The tag associated with the message.
16455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param message The message to output.
16555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
16655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public static void v(String tag, String message) {
16755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        println(LogLevel.VERBOSE, tag, message);
16855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
16955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
17055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
17155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Outputs a {@link LogLevel#DEBUG} level message.
17255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param tag The tag associated with the message.
17355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param message The message to output.
17455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
17555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public static void d(String tag, String message) {
17655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        println(LogLevel.DEBUG, tag, message);
17755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
17855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
17955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
18055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Outputs a {@link LogLevel#INFO} level message.
18155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param tag The tag associated with the message.
18255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param message The message to output.
18355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
18455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public static void i(String tag, String message) {
18555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        println(LogLevel.INFO, tag, message);
18655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
18755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
18855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
18955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Outputs a {@link LogLevel#WARN} level message.
19055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param tag The tag associated with the message.
19155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param message The message to output.
19255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
19355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public static void w(String tag, String message) {
19455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        println(LogLevel.WARN, tag, message);
19555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
19655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
19755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
19855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Outputs a {@link LogLevel#ERROR} level message.
19955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param tag The tag associated with the message.
20055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param message The message to output.
20155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
20255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public static void e(String tag, String message) {
20355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        println(LogLevel.ERROR, tag, message);
20455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
20555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
20655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
20755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Outputs a log message and attempts to display it in a dialog.
20855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param tag The tag associated with the message.
20955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param message The message to output.
21055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
21155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public static void logAndDisplay(LogLevel logLevel, String tag, String message) {
21255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        if (sLogOutput != null) {
21355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            sLogOutput.printAndPromptLog(logLevel, tag, message);
21455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        } else {
21555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            println(logLevel, tag, message);
21655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
21755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
21855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
21955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
22055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Outputs a {@link LogLevel#ERROR} level {@link Throwable} information.
22155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param tag The tag associated with the message.
22255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param throwable The {@link Throwable} to output.
22355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
22455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public static void e(String tag, Throwable throwable) {
22555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        if (throwable != null) {
22655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            StringWriter sw = new StringWriter();
22755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            PrintWriter pw = new PrintWriter(sw);
22855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
22955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            throwable.printStackTrace(pw);
23055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            println(LogLevel.ERROR, tag, throwable.getMessage() + '\n' + sw.toString());
23155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
23255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
23355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
23455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    static void setLevel(LogLevel logLevel) {
23555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        mLevel = logLevel;
23655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
23755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
23855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
23955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Sets the {@link ILogOutput} to use to print the logs. If not set, {@link System#out}
24055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * will be used.
24155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param logOutput The {@link ILogOutput} to use to print the log.
24255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
24355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public static void setLogOutput(ILogOutput logOutput) {
24455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        sLogOutput = logOutput;
24555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
24655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
24755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
24855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Show hex dump.
24955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * <p/>
25055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Local addition.  Output looks like:
25155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * 1230- 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef
25255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * <p/>
25355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Uses no string concatenation; creates one String object per line.
25455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
25555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    static void hexDump(String tag, LogLevel level, byte[] data, int offset, int length) {
25655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
25755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        int kHexOffset = 6;
25855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        int kAscOffset = 55;
25955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        char[] line = new char[mSpaceLine.length];
26055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        int addr, baseAddr, count;
26155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        int i, ch;
26255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        boolean needErase = true;
26355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
26455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        //Log.w(tag, "HEX DUMP: off=" + offset + ", length=" + length);
26555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
26655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        baseAddr = 0;
26755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        while (length != 0) {
26855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            if (length > 16) {
26955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                // full line
27055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                count = 16;
27155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            } else {
27255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                // partial line; re-copy blanks to clear end
27355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                count = length;
27455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                needErase = true;
27555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            }
27655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
27755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            if (needErase) {
27855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                System.arraycopy(mSpaceLine, 0, line, 0, mSpaceLine.length);
27955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                needErase = false;
28055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            }
28155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
28255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            // output the address (currently limited to 4 hex digits)
28355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            addr = baseAddr;
28455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            addr &= 0xffff;
28555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            ch = 3;
28655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            while (addr != 0) {
28755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                line[ch] = mHexDigit[addr & 0x0f];
28855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                ch--;
28955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                addr >>>= 4;
29055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            }
29155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
29255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            // output hex digits and ASCII chars
29355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            ch = kHexOffset;
29455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            for (i = 0; i < count; i++) {
29555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                byte val = data[offset + i];
29655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
29755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                line[ch++] = mHexDigit[(val >>> 4) & 0x0f];
29855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                line[ch++] = mHexDigit[val & 0x0f];
29955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                ch++;
30055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
30155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                if (val >= 0x20 && val < 0x7f)
30255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                    line[kAscOffset + i] = (char) val;
30355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                else
30455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                    line[kAscOffset + i] = '.';
30555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            }
30655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
30755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            println(level, tag, new String(line));
30855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
30955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            // advance to next chunk of data
31055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            length -= count;
31155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            offset += count;
31255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            baseAddr += count;
31355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
31455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
31555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
31655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
31755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
31855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Dump the entire contents of a byte array with DEBUG priority.
31955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
32055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    static void hexDump(byte[] data) {
32155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        hexDump("ddms", LogLevel.DEBUG, data, 0, data.length);
32255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
32355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
32455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /* currently prints to stdout; could write to a log window */
32555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    private static void println(LogLevel logLevel, String tag, String message) {
32655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        if (logLevel.getPriority() >= mLevel.getPriority()) {
32755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            if (sLogOutput != null) {
32855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                sLogOutput.printLog(logLevel, tag, message);
32955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            } else {
33055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                printLog(logLevel, tag, message);
33155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            }
33255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
33355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
33455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
33555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    /**
33655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * Prints a log message.
33755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param logLevel
33855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param tag
33955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     * @param message
34055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project     */
34155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public static void printLog(LogLevel logLevel, String tag, String message) {
34291f7f2acac96f2bf8b0cf726135652ccd92fc98fNeal Nguyen        System.out.print(getLogFormatString(logLevel, tag, message));
34391f7f2acac96f2bf8b0cf726135652ccd92fc98fNeal Nguyen    }
34491f7f2acac96f2bf8b0cf726135652ccd92fc98fNeal Nguyen
34591f7f2acac96f2bf8b0cf726135652ccd92fc98fNeal Nguyen    /**
34691f7f2acac96f2bf8b0cf726135652ccd92fc98fNeal Nguyen     * Formats a log message.
34791f7f2acac96f2bf8b0cf726135652ccd92fc98fNeal Nguyen     * @param logLevel
34891f7f2acac96f2bf8b0cf726135652ccd92fc98fNeal Nguyen     * @param tag
34991f7f2acac96f2bf8b0cf726135652ccd92fc98fNeal Nguyen     * @param message
35091f7f2acac96f2bf8b0cf726135652ccd92fc98fNeal Nguyen     */
35191f7f2acac96f2bf8b0cf726135652ccd92fc98fNeal Nguyen    public static String getLogFormatString(LogLevel logLevel, String tag, String message) {
352e551cd75cfbbdd4ab4040b7d5c290a715e944305Brett Chabot        SimpleDateFormat formatter = new SimpleDateFormat("hh:mm:ss");
353e551cd75cfbbdd4ab4040b7d5c290a715e944305Brett Chabot        return String.format("%s %c/%s: %s\n", formatter.format(new Date()),
35455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                logLevel.getPriorityLetter(), tag, message);
35555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
35655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project}
35755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
35855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
359