Merge pull request #10185 from TiVo:p-custom-logger

PiperOrigin-RevId: 460689252
This commit is contained in:
Rohit Singh 2022-07-13 17:45:54 +00:00
commit bd8723e35a
2 changed files with 132 additions and 26 deletions

View File

@ -12,6 +12,8 @@
* Add `ExoPlayer.isTunnelingEnabled` to check if tunneling is enabled for * Add `ExoPlayer.isTunnelingEnabled` to check if tunneling is enabled for
the currently selected tracks the currently selected tracks
([#2518](https://github.com/google/ExoPlayer/issues/2518)). ([#2518](https://github.com/google/ExoPlayer/issues/2518)).
* Allow custom logger for all ExoPlayer log output
([#9752](https://github.com/google/ExoPlayer/issues/9752)).
* Extractors: * Extractors:
* Add support for AVI * Add support for AVI
([#2092](https://github.com/google/ExoPlayer/issues/2092)). ([#2092](https://github.com/google/ExoPlayer/issues/2092)).

View File

@ -18,6 +18,7 @@ package androidx.media3.common.util;
import static java.lang.annotation.ElementType.TYPE_USE; import static java.lang.annotation.ElementType.TYPE_USE;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.GuardedBy;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.Size; import androidx.annotation.Size;
@ -28,7 +29,10 @@ import java.lang.annotation.Target;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.Pure;
/** Wrapper around {@link android.util.Log} which allows to set the log level. */ /**
* Wrapper around {@link android.util.Log} which allows to set the log level and to specify a custom
* log output.
*/
@UnstableApi @UnstableApi
public final class Log { public final class Log {
@ -52,16 +56,90 @@ public final class Log {
/** Log level to disable all logging. */ /** Log level to disable all logging. */
public static final int LOG_LEVEL_OFF = Integer.MAX_VALUE; public static final int LOG_LEVEL_OFF = Integer.MAX_VALUE;
/**
* Interface for a logger that can output messages with a tag.
*
* <p>Use {@link #DEFAULT} to output to {@link android.util.Log}.
*/
public interface Logger {
/** The default instance logging to {@link android.util.Log}. */
Logger DEFAULT =
new Logger() {
@Override
public void d(String tag, String message) {
android.util.Log.d(tag, message);
}
@Override
public void i(String tag, String message) {
android.util.Log.i(tag, message);
}
@Override
public void w(String tag, String message) {
android.util.Log.w(tag, message);
}
@Override
public void e(String tag, String message) {
android.util.Log.e(tag, message);
}
};
/**
* Logs a debug-level message.
*
* @param tag The tag of the message.
* @param message The message.
*/
void d(String tag, String message);
/**
* Logs an information-level message.
*
* @param tag The tag of the message.
* @param message The message.
*/
void i(String tag, String message);
/**
* Logs a warning-level message.
*
* @param tag The tag of the message.
* @param message The message.
*/
void w(String tag, String message);
/**
* Logs an error-level message.
*
* @param tag The tag of the message.
* @param message The message.
*/
void e(String tag, String message);
}
private static final Object lock = new Object();
@GuardedBy("lock")
private static int logLevel = LOG_LEVEL_ALL; private static int logLevel = LOG_LEVEL_ALL;
@GuardedBy("lock")
private static boolean logStackTraces = true; private static boolean logStackTraces = true;
@GuardedBy("lock")
private static Logger logger = Logger.DEFAULT;
private Log() {} private Log() {}
/** Returns current {@link LogLevel} for ExoPlayer logcat logging. */ /** Returns current {@link LogLevel} for ExoPlayer logcat logging. */
@Pure @Pure
public static @LogLevel int getLogLevel() { public static @LogLevel int getLogLevel() {
synchronized (lock) {
return logLevel; return logLevel;
} }
}
/** /**
* Sets the {@link LogLevel} for ExoPlayer logcat logging. * Sets the {@link LogLevel} for ExoPlayer logcat logging.
@ -69,8 +147,10 @@ public final class Log {
* @param logLevel The new {@link LogLevel}. * @param logLevel The new {@link LogLevel}.
*/ */
public static void setLogLevel(@LogLevel int logLevel) { public static void setLogLevel(@LogLevel int logLevel) {
synchronized (lock) {
Log.logLevel = logLevel; Log.logLevel = logLevel;
} }
}
/** /**
* Sets whether stack traces of {@link Throwable}s will be logged to logcat. Stack trace logging * Sets whether stack traces of {@link Throwable}s will be logged to logcat. Stack trace logging
@ -79,16 +159,31 @@ public final class Log {
* @param logStackTraces Whether stack traces will be logged. * @param logStackTraces Whether stack traces will be logged.
*/ */
public static void setLogStackTraces(boolean logStackTraces) { public static void setLogStackTraces(boolean logStackTraces) {
synchronized (lock) {
Log.logStackTraces = logStackTraces; Log.logStackTraces = logStackTraces;
} }
}
/**
* Sets a custom {@link Logger} as the output.
*
* @param logger The {@link Logger}.
*/
public static void setLogger(Logger logger) {
synchronized (lock) {
Log.logger = logger;
}
}
/** /**
* @see android.util.Log#d(String, String) * @see android.util.Log#d(String, String)
*/ */
@Pure @Pure
public static void d(@Size(max = 23) String tag, String message) { public static void d(@Size(max = 23) String tag, String message) {
synchronized (lock) {
if (logLevel == LOG_LEVEL_ALL) { if (logLevel == LOG_LEVEL_ALL) {
android.util.Log.d(tag, message); logger.d(tag, message);
}
} }
} }
@ -105,8 +200,10 @@ public final class Log {
*/ */
@Pure @Pure
public static void i(@Size(max = 23) String tag, String message) { public static void i(@Size(max = 23) String tag, String message) {
synchronized (lock) {
if (logLevel <= LOG_LEVEL_INFO) { if (logLevel <= LOG_LEVEL_INFO) {
android.util.Log.i(tag, message); logger.i(tag, message);
}
} }
} }
@ -123,8 +220,10 @@ public final class Log {
*/ */
@Pure @Pure
public static void w(@Size(max = 23) String tag, String message) { public static void w(@Size(max = 23) String tag, String message) {
synchronized (lock) {
if (logLevel <= LOG_LEVEL_WARNING) { if (logLevel <= LOG_LEVEL_WARNING) {
android.util.Log.w(tag, message); logger.w(tag, message);
}
} }
} }
@ -141,8 +240,10 @@ public final class Log {
*/ */
@Pure @Pure
public static void e(@Size(max = 23) String tag, String message) { public static void e(@Size(max = 23) String tag, String message) {
synchronized (lock) {
if (logLevel <= LOG_LEVEL_ERROR) { if (logLevel <= LOG_LEVEL_ERROR) {
android.util.Log.e(tag, message); logger.e(tag, message);
}
} }
} }
@ -168,11 +269,13 @@ public final class Log {
@Nullable @Nullable
@Pure @Pure
public static String getThrowableString(@Nullable Throwable throwable) { public static String getThrowableString(@Nullable Throwable throwable) {
synchronized (lock) {
if (throwable == null) { if (throwable == null) {
return null; return null;
} else if (isCausedByUnknownHostException(throwable)) { } else if (isCausedByUnknownHostException(throwable)) {
// UnknownHostException implies the device doesn't have network connectivity. // UnknownHostException implies the device doesn't have network connectivity.
// UnknownHostException.getMessage() may return a string that's more verbose than desired for // UnknownHostException.getMessage() may return a string that's more verbose than desired
// for
// logging an expected failure mode. Conversely, android.util.Log.getStackTraceString has // logging an expected failure mode. Conversely, android.util.Log.getStackTraceString has
// special handling to return the empty string, which can result in logging that doesn't // special handling to return the empty string, which can result in logging that doesn't
// indicate the failure mode at all. Hence we special case this exception to always return a // indicate the failure mode at all. Hence we special case this exception to always return a
@ -184,6 +287,7 @@ public final class Log {
return android.util.Log.getStackTraceString(throwable).trim().replace("\t", " "); return android.util.Log.getStackTraceString(throwable).trim().replace("\t", " ");
} }
} }
}
@Pure @Pure
private static String appendThrowableString(String message, @Nullable Throwable throwable) { private static String appendThrowableString(String message, @Nullable Throwable throwable) {