diff --git a/RELEASENOTES.md b/RELEASENOTES.md index a795841ee8..2d9601dbf6 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -162,8 +162,8 @@ format-related information. ([#9175](https://github.com/google/ExoPlayer/issues/9175)). * SS: - * Propagate `StreamIndex` element `Name` attribute value as `Format` - label ([#9252](https://github.com/google/ExoPlayer/issues/9252)). + * Propagate `StreamIndex` element `Name` attribute value as `Format` label + ([#9252](https://github.com/google/ExoPlayer/issues/9252)). ### 2.14.2 (2021-07-20) diff --git a/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspClient.java b/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspClient.java index 0c4cff6446..45d7bcad9a 100644 --- a/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspClient.java +++ b/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspClient.java @@ -47,7 +47,9 @@ import com.google.android.exoplayer2.source.rtsp.RtspMediaSource.RtspPlaybackExc import com.google.android.exoplayer2.source.rtsp.RtspMessageChannel.InterleavedBinaryDataListener; import com.google.android.exoplayer2.source.rtsp.RtspMessageUtil.RtspAuthUserInfo; import com.google.android.exoplayer2.source.rtsp.RtspMessageUtil.RtspSessionHeader; +import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Util; +import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; @@ -65,6 +67,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /** The RTSP client. */ /* package */ final class RtspClient implements Closeable { + private static final String TAG = "RtspClient"; private static final long DEFAULT_RTSP_KEEP_ALIVE_INTERVAL_MS = 30_000; /** A listener for session information update. */ @@ -100,6 +103,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private final Uri uri; @Nullable private final RtspAuthUserInfo rtspAuthUserInfo; private final String userAgent; + private final boolean debugLoggingEnabled; private final ArrayDeque pendingSetupRtpLoadInfos; // TODO(b/172331505) Add a timeout monitor for pending requests. private final SparseArray pendingRequests; @@ -131,12 +135,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; SessionInfoListener sessionInfoListener, PlaybackEventListener playbackEventListener, String userAgent, - Uri uri) { + Uri uri, + boolean debugLoggingEnabled) { this.sessionInfoListener = sessionInfoListener; this.playbackEventListener = playbackEventListener; this.uri = RtspMessageUtil.removeUserInfo(uri); this.rtspAuthUserInfo = RtspMessageUtil.parseUserInfo(uri); this.userAgent = userAgent; + this.debugLoggingEnabled = debugLoggingEnabled; pendingSetupRtpLoadInfos = new ArrayDeque<>(); pendingRequests = new SparseArray<>(); messageSender = new MessageSender(); @@ -241,6 +247,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; messageSender.sendSetupRequest(loadInfo.getTrackUri(), loadInfo.getTransport(), sessionId); } + private void maybeLogMessage(List message) { + if (debugLoggingEnabled) { + Log.d(TAG, Joiner.on("\n").join(message)); + } + } + /** Returns a {@link Socket} that is connected to the {@code uri}. */ private static Socket getSocket(Uri uri) throws IOException { checkArgument(uri.getHost() != null); @@ -396,7 +408,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; int cSeq = Integer.parseInt(checkNotNull(request.headers.get(RtspHeaders.CSEQ))); checkState(pendingRequests.get(cSeq) == null); pendingRequests.append(cSeq, request); - messageChannel.send(RtspMessageUtil.serializeRequest(request)); + List message = RtspMessageUtil.serializeRequest(request); + maybeLogMessage(message); + messageChannel.send(message); lastRequest = request; } } @@ -421,6 +435,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } private void handleRtspMessage(List message) { + maybeLogMessage(message); RtspResponse response = RtspMessageUtil.parseResponse(message); int cSeq = Integer.parseInt(checkNotNull(response.headers.get(RtspHeaders.CSEQ))); diff --git a/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMediaPeriod.java b/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMediaPeriod.java index 14bcdfceb6..435bb59a30 100644 --- a/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMediaPeriod.java +++ b/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMediaPeriod.java @@ -108,7 +108,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; RtpDataChannel.Factory rtpDataChannelFactory, Uri uri, Listener listener, - String userAgent) { + String userAgent, + boolean debugLoggingEnabled) { this.allocator = allocator; this.rtpDataChannelFactory = rtpDataChannelFactory; this.listener = listener; @@ -120,7 +121,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /* sessionInfoListener= */ internalListener, /* playbackEventListener= */ internalListener, /* userAgent= */ userAgent, - /* uri= */ uri); + /* uri= */ uri, + debugLoggingEnabled); rtspLoaderWrappers = new ArrayList<>(); selectedLoadInfos = new ArrayList<>(); diff --git a/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMediaSource.java b/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMediaSource.java index 89cbaeddb3..688c2f40b3 100644 --- a/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMediaSource.java +++ b/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMediaSource.java @@ -69,6 +69,7 @@ public final class RtspMediaSource extends BaseMediaSource { private long timeoutMs; private String userAgent; private boolean forceUseRtpTcp; + private boolean debugLoggingEnabled; public Factory() { timeoutMs = DEFAULT_TIMEOUT_MS; @@ -102,6 +103,20 @@ public final class RtspMediaSource extends BaseMediaSource { return this; } + /** + * Sets whether to log RTSP messages, the default value is {@code false}. + * + *

This option presents a privacy risk, since it may expose sensitive information such as + * user's credentials. + * + * @param debugLoggingEnabled Whether to log RTSP messages. + * @return This Factory, for convenience. + */ + public Factory setDebugLoggingEnabled(boolean debugLoggingEnabled) { + this.debugLoggingEnabled = debugLoggingEnabled; + return this; + } + /** * Sets the timeout in milliseconds, the default value is {@link #DEFAULT_TIMEOUT_MS}. * @@ -186,7 +201,8 @@ public final class RtspMediaSource extends BaseMediaSource { forceUseRtpTcp ? new TransferRtpDataChannelFactory(timeoutMs) : new UdpDataSourceRtpDataChannelFactory(timeoutMs), - userAgent); + userAgent, + debugLoggingEnabled); } } @@ -209,6 +225,7 @@ public final class RtspMediaSource extends BaseMediaSource { private final RtpDataChannel.Factory rtpDataChannelFactory; private final String userAgent; private final Uri uri; + private final boolean debugLoggingEnabled; private long timelineDurationUs; private boolean timelineIsSeekable; @@ -217,11 +234,15 @@ public final class RtspMediaSource extends BaseMediaSource { @VisibleForTesting /* package */ RtspMediaSource( - MediaItem mediaItem, RtpDataChannel.Factory rtpDataChannelFactory, String userAgent) { + MediaItem mediaItem, + RtpDataChannel.Factory rtpDataChannelFactory, + String userAgent, + boolean debugLoggingEnabled) { this.mediaItem = mediaItem; this.rtpDataChannelFactory = rtpDataChannelFactory; this.userAgent = userAgent; this.uri = checkNotNull(this.mediaItem.playbackProperties).uri; + this.debugLoggingEnabled = debugLoggingEnabled; this.timelineDurationUs = C.TIME_UNSET; this.timelineIsPlaceholder = true; } @@ -259,7 +280,8 @@ public final class RtspMediaSource extends BaseMediaSource { timelineIsPlaceholder = false; notifySourceInfoRefreshed(); }, - userAgent); + userAgent, + debugLoggingEnabled); } @Override diff --git a/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspClientTest.java b/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspClientTest.java index 129871c584..15237d1003 100644 --- a/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspClientTest.java +++ b/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspClientTest.java @@ -112,7 +112,8 @@ public final class RtspClientTest { }, EMPTY_PLAYBACK_LISTENER, /* userAgent= */ "ExoPlayer:RtspClientTest", - RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber())); + RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()), + /* debugLoggingEnabled= */ false); rtspClient.start(); RobolectricUtil.runMainLooperUntil(() -> tracksInSession.get() != null); @@ -153,7 +154,8 @@ public final class RtspClientTest { }, EMPTY_PLAYBACK_LISTENER, /* userAgent= */ "ExoPlayer:RtspClientTest", - RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber())); + RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()), + /* debugLoggingEnabled= */ false); rtspClient.start(); RobolectricUtil.runMainLooperUntil(() -> tracksInSession.get() != null); @@ -197,7 +199,8 @@ public final class RtspClientTest { }, EMPTY_PLAYBACK_LISTENER, /* userAgent= */ "ExoPlayer:RtspClientTest", - RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber())); + RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()), + /* debugLoggingEnabled= */ false); rtspClient.start(); RobolectricUtil.runMainLooperUntil(() -> failureMessage.get() != null); @@ -241,7 +244,8 @@ public final class RtspClientTest { }, EMPTY_PLAYBACK_LISTENER, /* userAgent= */ "ExoPlayer:RtspClientTest", - RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber())); + RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()), + /* debugLoggingEnabled= */ false); rtspClient.start(); RobolectricUtil.runMainLooperUntil(() -> failureCause.get() != null); diff --git a/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspMediaPeriodTest.java b/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspMediaPeriodTest.java index 9072103958..da7da55d8e 100644 --- a/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspMediaPeriodTest.java +++ b/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspMediaPeriodTest.java @@ -83,7 +83,8 @@ public final class RtspMediaPeriodTest { new TransferRtpDataChannelFactory(DEFAULT_TIMEOUT_MS), RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()), /* listener= */ timing -> refreshedSourceDurationMs.set(timing.getDurationMs()), - /* userAgent= */ "ExoPlayer:RtspPeriodTest"); + /* userAgent= */ "ExoPlayer:RtspPeriodTest", + /* debugLoggingEnabled= */ false); mediaPeriod.prepare( new MediaPeriod.Callback() { diff --git a/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspPlaybackTest.java b/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspPlaybackTest.java index e46737d3d7..61cde4a725 100644 --- a/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspPlaybackTest.java +++ b/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspPlaybackTest.java @@ -157,7 +157,9 @@ public final class RtspPlaybackTest { new RtspMediaSource( MediaItem.fromUri(RtspTestUtils.getTestUri(serverRtspPortNumber)), rtpDataChannelFactory, - "ExoPlayer:PlaybackTest")); + "ExoPlayer:PlaybackTest", + /* debugLoggingEnabled= */ false), + false); return player; }