diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/upstream/CmcdHeadersFactory.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/upstream/CmcdHeadersFactory.java index b29bf5c4c3..d09f52983f 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/upstream/CmcdHeadersFactory.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/upstream/CmcdHeadersFactory.java @@ -29,12 +29,14 @@ import androidx.media3.common.TrackGroup; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; import androidx.media3.exoplayer.trackselection.ExoTrackSelection; +import com.google.common.base.Joiner; import com.google.common.collect.ImmutableMap; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.ArrayList; /** * This class serves as a factory for generating Common Media Client Data (CMCD) HTTP request @@ -47,6 +49,8 @@ import java.lang.annotation.Target; @UnstableApi public final class CmcdHeadersFactory { + private static final Joiner COMMA_JOINER = Joiner.on(","); + /** * Retrieves the object type value from the given {@link ExoTrackSelection}. * @@ -426,34 +430,27 @@ public final class CmcdHeadersFactory { */ public void populateHttpRequestHeaders( ImmutableMap.Builder<@CmcdConfiguration.HeaderKey String, String> httpRequestHeaders) { - StringBuilder headerValue = new StringBuilder(); + ArrayList headerValueList = new ArrayList<>(); if (bitrateKbps != C.RATE_UNSET_INT) { - headerValue.append( - Util.formatInvariant("%s=%d,", CmcdConfiguration.KEY_BITRATE, bitrateKbps)); + headerValueList.add(CmcdConfiguration.KEY_BITRATE + "=" + bitrateKbps); } if (topBitrateKbps != C.RATE_UNSET_INT) { - headerValue.append( - Util.formatInvariant("%s=%d,", CmcdConfiguration.KEY_TOP_BITRATE, topBitrateKbps)); + headerValueList.add(CmcdConfiguration.KEY_TOP_BITRATE + "=" + topBitrateKbps); } if (objectDurationMs != C.TIME_UNSET) { - headerValue.append( - Util.formatInvariant( - "%s=%d,", CmcdConfiguration.KEY_OBJECT_DURATION, objectDurationMs)); + headerValueList.add(CmcdConfiguration.KEY_OBJECT_DURATION + "=" + objectDurationMs); } if (!TextUtils.isEmpty(objectType)) { - headerValue.append( - Util.formatInvariant("%s=%s,", CmcdConfiguration.KEY_OBJECT_TYPE, objectType)); + headerValueList.add(CmcdConfiguration.KEY_OBJECT_TYPE + "=" + objectType); } if (!TextUtils.isEmpty(customData)) { - headerValue.append(Util.formatInvariant("%s,", customData)); + headerValueList.add(customData); } - if (headerValue.length() == 0) { - return; + if (!headerValueList.isEmpty()) { + httpRequestHeaders.put( + CmcdConfiguration.KEY_CMCD_OBJECT, COMMA_JOINER.join(headerValueList)); } - // Remove the trailing comma as headerValue is not empty - headerValue.setLength(headerValue.length() - 1); - httpRequestHeaders.put(CmcdConfiguration.KEY_CMCD_OBJECT, headerValue.toString()); } } @@ -606,36 +603,28 @@ public final class CmcdHeadersFactory { */ public void populateHttpRequestHeaders( ImmutableMap.Builder<@CmcdConfiguration.HeaderKey String, String> httpRequestHeaders) { - StringBuilder headerValue = new StringBuilder(); + ArrayList headerValueList = new ArrayList<>(); if (bufferLengthMs != C.TIME_UNSET) { - headerValue.append( - Util.formatInvariant("%s=%d,", CmcdConfiguration.KEY_BUFFER_LENGTH, bufferLengthMs)); + headerValueList.add(CmcdConfiguration.KEY_BUFFER_LENGTH + "=" + bufferLengthMs); } if (measuredThroughputInKbps != Long.MIN_VALUE) { - headerValue.append( - Util.formatInvariant( - "%s=%d,", CmcdConfiguration.KEY_MEASURED_THROUGHPUT, measuredThroughputInKbps)); + headerValueList.add( + CmcdConfiguration.KEY_MEASURED_THROUGHPUT + "=" + measuredThroughputInKbps); } if (deadlineMs != C.TIME_UNSET) { - headerValue - .append(CmcdConfiguration.KEY_DEADLINE) - .append("=") - .append(deadlineMs) - .append(","); + headerValueList.add(CmcdConfiguration.KEY_DEADLINE + "=" + deadlineMs); } if (startup) { - headerValue.append(CmcdConfiguration.KEY_STARTUP).append(","); + headerValueList.add(CmcdConfiguration.KEY_STARTUP); } if (!TextUtils.isEmpty(customData)) { - headerValue.append(Util.formatInvariant("%s,", customData)); + headerValueList.add(customData); } - if (headerValue.length() == 0) { - return; + if (!headerValueList.isEmpty()) { + httpRequestHeaders.put( + CmcdConfiguration.KEY_CMCD_REQUEST, COMMA_JOINER.join(headerValueList)); } - // Remove the trailing comma as headerValue is not empty - headerValue.setLength(headerValue.length() - 1); - httpRequestHeaders.put(CmcdConfiguration.KEY_CMCD_REQUEST, headerValue.toString()); } } @@ -788,41 +777,36 @@ public final class CmcdHeadersFactory { */ public void populateHttpRequestHeaders( ImmutableMap.Builder<@CmcdConfiguration.HeaderKey String, String> httpRequestHeaders) { - StringBuilder headerValue = new StringBuilder(); + ArrayList headerValueList = new ArrayList<>(); if (!TextUtils.isEmpty(this.contentId)) { - headerValue.append( - Util.formatInvariant("%s=\"%s\",", CmcdConfiguration.KEY_CONTENT_ID, contentId)); + headerValueList.add( + Util.formatInvariant("%s=\"%s\"", CmcdConfiguration.KEY_CONTENT_ID, contentId)); } if (!TextUtils.isEmpty(this.sessionId)) { - headerValue.append( - Util.formatInvariant("%s=\"%s\",", CmcdConfiguration.KEY_SESSION_ID, sessionId)); + headerValueList.add( + Util.formatInvariant("%s=\"%s\"", CmcdConfiguration.KEY_SESSION_ID, sessionId)); } if (!TextUtils.isEmpty(this.streamingFormat)) { - headerValue.append( - Util.formatInvariant( - "%s=%s,", CmcdConfiguration.KEY_STREAMING_FORMAT, streamingFormat)); + headerValueList.add(CmcdConfiguration.KEY_STREAMING_FORMAT + "=" + streamingFormat); } if (!TextUtils.isEmpty(this.streamType)) { - headerValue.append( - Util.formatInvariant("%s=%s,", CmcdConfiguration.KEY_STREAM_TYPE, streamType)); + headerValueList.add(CmcdConfiguration.KEY_STREAM_TYPE + "=" + streamType); } if (playbackRate != C.RATE_UNSET && playbackRate != 1.0f) { - headerValue.append( - Util.formatInvariant("%s=%.2f,", CmcdConfiguration.KEY_PLAYBACK_RATE, playbackRate)); + headerValueList.add( + Util.formatInvariant("%s=%.2f", CmcdConfiguration.KEY_PLAYBACK_RATE, playbackRate)); } if (VERSION != 1) { - headerValue.append(Util.formatInvariant("%s=%d,", CmcdConfiguration.KEY_VERSION, VERSION)); + headerValueList.add(CmcdConfiguration.KEY_VERSION + "=" + VERSION); } if (!TextUtils.isEmpty(customData)) { - headerValue.append(Util.formatInvariant("%s,", customData)); + headerValueList.add(customData); } - if (headerValue.length() == 0) { - return; + if (!headerValueList.isEmpty()) { + httpRequestHeaders.put( + CmcdConfiguration.KEY_CMCD_SESSION, COMMA_JOINER.join(headerValueList)); } - // Remove the trailing comma as headerValue is not empty - headerValue.setLength(headerValue.length() - 1); - httpRequestHeaders.put(CmcdConfiguration.KEY_CMCD_SESSION, headerValue.toString()); } } @@ -920,26 +904,22 @@ public final class CmcdHeadersFactory { */ public void populateHttpRequestHeaders( ImmutableMap.Builder<@CmcdConfiguration.HeaderKey String, String> httpRequestHeaders) { - StringBuilder headerValue = new StringBuilder(); + ArrayList headerValueList = new ArrayList<>(); if (maximumRequestedThroughputKbps != C.RATE_UNSET_INT) { - headerValue.append( - Util.formatInvariant( - "%s=%d,", - CmcdConfiguration.KEY_MAXIMUM_REQUESTED_BITRATE, maximumRequestedThroughputKbps)); + headerValueList.add( + CmcdConfiguration.KEY_MAXIMUM_REQUESTED_BITRATE + "=" + maximumRequestedThroughputKbps); } if (bufferStarvation) { - headerValue.append(CmcdConfiguration.KEY_BUFFER_STARVATION).append(","); + headerValueList.add(CmcdConfiguration.KEY_BUFFER_STARVATION); } if (!TextUtils.isEmpty(customData)) { - headerValue.append(Util.formatInvariant("%s,", customData)); + headerValueList.add(customData); } - if (headerValue.length() == 0) { - return; + if (!headerValueList.isEmpty()) { + httpRequestHeaders.put( + CmcdConfiguration.KEY_CMCD_STATUS, COMMA_JOINER.join(headerValueList)); } - // Remove the trailing comma as headerValue is not empty - headerValue.setLength(headerValue.length() - 1); - httpRequestHeaders.put(CmcdConfiguration.KEY_CMCD_STATUS, headerValue.toString()); } } }