diff --git a/libraries/common/src/main/java/androidx/media3/common/util/Util.java b/libraries/common/src/main/java/androidx/media3/common/util/Util.java index d2936003ee..12f9388982 100644 --- a/libraries/common/src/main/java/androidx/media3/common/util/Util.java +++ b/libraries/common/src/main/java/androidx/media3/common/util/Util.java @@ -92,8 +92,10 @@ import androidx.media3.common.Player.Commands; import androidx.media3.common.audio.AudioProcessor; import com.google.common.base.Ascii; import com.google.common.base.Charsets; +import com.google.common.io.ByteStreams; import com.google.common.math.DoubleMath; import com.google.common.math.LongMath; +import com.google.common.primitives.Ints; import com.google.common.primitives.UnsignedBytes; import com.google.common.util.concurrent.AsyncFunction; import com.google.common.util.concurrent.Futures; @@ -203,47 +205,30 @@ public final class Util { private Util() {} /** - * Converts the entirety of an {@link InputStream} to a byte array. - * - * @param inputStream the {@link InputStream} to be read. The input stream is not closed by this - * method. - * @return a byte array containing all of the inputStream's bytes. - * @throws IOException if an error occurs reading from the stream. + * @deprecated Use Guava's {@link ByteStreams#toByteArray(InputStream)} instead. */ @UnstableApi + @Deprecated public static byte[] toByteArray(InputStream inputStream) throws IOException { - byte[] buffer = new byte[1024 * 4]; - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - int bytesRead; - while ((bytesRead = inputStream.read(buffer)) != -1) { - outputStream.write(buffer, 0, bytesRead); - } - return outputStream.toByteArray(); - } - - /** Converts an integer into an equivalent byte array. */ - @UnstableApi - public static byte[] toByteArray(int value) { - return new byte[] { - (byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value - }; + return ByteStreams.toByteArray(inputStream); } /** * Converts an array of integers into an equivalent byte array. * *

Each integer is converted into 4 sequential bytes. + * + *

For a single integer, prefer Guava's {@link Ints#toByteArray(int)} implementation. */ @UnstableApi public static byte[] toByteArray(int... values) { byte[] array = new byte[values.length * 4]; int index = 0; for (int value : values) { - byte[] byteArray = toByteArray(value); - array[index++] = byteArray[0]; - array[index++] = byteArray[1]; - array[index++] = byteArray[2]; - array[index++] = byteArray[3]; + array[index++] = (byte) (value >> 24); + array[index++] = (byte) (value >> 16); + array[index++] = (byte) (value >> 8); + array[index++] = (byte) (value); } return array; } @@ -251,23 +236,7 @@ public final class Util { /** Converts a float into an equivalent byte array. */ @UnstableApi public static byte[] toByteArray(float value) { - return toByteArray(Float.floatToIntBits(value)); - } - - /** Converts a byte array into a float. */ - @UnstableApi - public static float toFloat(byte[] bytes) { - checkArgument(bytes.length == 4); - int intBits = - bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF); - return Float.intBitsToFloat(intBits); - } - - /** Converts a byte array into an integer. */ - @UnstableApi - public static int toInteger(byte[] bytes) { - checkArgument(bytes.length == 4); - return bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]; + return Ints.toByteArray(Float.floatToIntBits(value)); } /** @@ -1060,7 +1029,7 @@ public final class Util { @Nullable InputStream inputStream = null; try { inputStream = context.getAssets().open(assetPath); - return Util.fromUtf8Bytes(Util.toByteArray(inputStream)); + return Util.fromUtf8Bytes(ByteStreams.toByteArray(inputStream)); } finally { Util.closeQuietly(inputStream); } diff --git a/libraries/container/src/main/java/androidx/media3/container/MdtaMetadataEntry.java b/libraries/container/src/main/java/androidx/media3/container/MdtaMetadataEntry.java index 93c47fc7f6..40c223624b 100644 --- a/libraries/container/src/main/java/androidx/media3/container/MdtaMetadataEntry.java +++ b/libraries/container/src/main/java/androidx/media3/container/MdtaMetadataEntry.java @@ -21,6 +21,7 @@ import androidx.annotation.Nullable; import androidx.media3.common.Metadata; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; +import com.google.common.primitives.Ints; import java.util.Arrays; /** @@ -113,10 +114,10 @@ public final class MdtaMetadataEntry implements Metadata.Entry { formattedValue = Util.fromUtf8Bytes(value); break; case TYPE_INDICATOR_FLOAT32: - formattedValue = String.valueOf(Util.toFloat(value)); + formattedValue = String.valueOf(Float.intBitsToFloat(Ints.fromByteArray(value))); break; case TYPE_INDICATOR_INT32: - formattedValue = String.valueOf(Util.toInteger(value)); + formattedValue = String.valueOf(Ints.fromByteArray(value)); break; default: formattedValue = Util.toHexString(value); diff --git a/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultHttpDataSource.java b/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultHttpDataSource.java index 6a9a1d8af5..c43e6ddd25 100644 --- a/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultHttpDataSource.java +++ b/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultHttpDataSource.java @@ -33,6 +33,7 @@ import com.google.common.base.Predicate; import com.google.common.collect.ForwardingMap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; +import com.google.common.io.ByteStreams; import com.google.common.net.HttpHeaders; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.io.IOException; @@ -423,7 +424,7 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou byte[] errorResponseBody; try { errorResponseBody = - errorStream != null ? Util.toByteArray(errorStream) : Util.EMPTY_BYTE_ARRAY; + errorStream != null ? ByteStreams.toByteArray(errorStream) : Util.EMPTY_BYTE_ARRAY; } catch (IOException e) { errorResponseBody = Util.EMPTY_BYTE_ARRAY; } diff --git a/libraries/datasource/src/test/java/androidx/media3/datasource/cache/SimpleCacheTest.java b/libraries/datasource/src/test/java/androidx/media3/datasource/cache/SimpleCacheTest.java index 758921e2d3..38e1d441a5 100644 --- a/libraries/datasource/src/test/java/androidx/media3/datasource/cache/SimpleCacheTest.java +++ b/libraries/datasource/src/test/java/androidx/media3/datasource/cache/SimpleCacheTest.java @@ -16,7 +16,6 @@ package androidx.media3.datasource.cache; import static androidx.media3.common.C.LENGTH_UNSET; -import static androidx.media3.common.util.Util.toByteArray; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.doAnswer; @@ -28,6 +27,7 @@ import androidx.media3.datasource.cache.Cache.CacheException; import androidx.media3.test.utils.TestUtil; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.google.common.io.ByteStreams; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -646,7 +646,7 @@ public class SimpleCacheTest { assertThat(cacheSpan.isCached).isTrue(); byte[] expected = generateData(cacheSpan.key, (int) cacheSpan.position, (int) cacheSpan.length); try (FileInputStream inputStream = new FileInputStream(cacheSpan.file)) { - assertThat(toByteArray(inputStream)).isEqualTo(expected); + assertThat(ByteStreams.toByteArray(inputStream)).isEqualTo(expected); } } diff --git a/libraries/datasource_okhttp/src/main/java/androidx/media3/datasource/okhttp/OkHttpDataSource.java b/libraries/datasource_okhttp/src/main/java/androidx/media3/datasource/okhttp/OkHttpDataSource.java index e360989db8..c72796405d 100644 --- a/libraries/datasource_okhttp/src/main/java/androidx/media3/datasource/okhttp/OkHttpDataSource.java +++ b/libraries/datasource_okhttp/src/main/java/androidx/media3/datasource/okhttp/OkHttpDataSource.java @@ -32,12 +32,10 @@ import androidx.media3.datasource.DataSource; import androidx.media3.datasource.DataSourceException; import androidx.media3.datasource.DataSpec; import androidx.media3.datasource.HttpDataSource; -import androidx.media3.datasource.HttpDataSource.HttpDataSourceException; -import androidx.media3.datasource.HttpDataSource.InvalidContentTypeException; -import androidx.media3.datasource.HttpDataSource.InvalidResponseCodeException; import androidx.media3.datasource.HttpUtil; import androidx.media3.datasource.TransferListener; import com.google.common.base.Predicate; +import com.google.common.io.ByteStreams; import com.google.common.net.HttpHeaders; import com.google.common.util.concurrent.SettableFuture; import com.google.errorprone.annotations.CanIgnoreReturnValue; @@ -338,7 +336,7 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource { byte[] errorResponseBody; try { - errorResponseBody = Util.toByteArray(Assertions.checkNotNull(responseByteStream)); + errorResponseBody = ByteStreams.toByteArray(Assertions.checkNotNull(responseByteStream)); } catch (IOException e) { errorResponseBody = Util.EMPTY_BYTE_ARRAY; } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/HttpMediaDrmCallback.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/HttpMediaDrmCallback.java index 95eb55e4d6..8973607d02 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/HttpMediaDrmCallback.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/HttpMediaDrmCallback.java @@ -30,6 +30,7 @@ import androidx.media3.datasource.StatsDataSource; import androidx.media3.exoplayer.drm.ExoMediaDrm.KeyRequest; import androidx.media3.exoplayer.drm.ExoMediaDrm.ProvisionRequest; import com.google.common.collect.ImmutableMap; +import com.google.common.io.ByteStreams; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -182,7 +183,7 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback { while (true) { DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec); try { - return Util.toByteArray(inputStream); + return ByteStreams.toByteArray(inputStream); } catch (InvalidResponseCodeException e) { @Nullable String redirectUrl = getRedirectUrl(e, manualRedirectCount); if (redirectUrl == null) { diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/MetadataRetrieverTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/MetadataRetrieverTest.java index 4654c30b45..a41c383e49 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/MetadataRetrieverTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/MetadataRetrieverTest.java @@ -40,6 +40,7 @@ import androidx.media3.test.utils.FakeClock; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.common.collect.ImmutableList; +import com.google.common.primitives.Ints; import com.google.common.util.concurrent.ListenableFuture; import java.util.ArrayList; import java.util.List; @@ -166,7 +167,7 @@ public class MetadataRetrieverTest { MdtaMetadataEntry expectedTemporalLayersCountMetdata = new MdtaMetadataEntry( /* key= */ "com.android.video.temporal_layers_count", - /* value= */ Util.toByteArray(4), + /* value= */ Ints.toByteArray(4), MdtaMetadataEntry.TYPE_INDICATOR_INT32); SmtaMetadataEntry expectedSmtaEntry = new SmtaMetadataEntry(/* captureFrameRate= */ 240, /* svcTemporalLayerCount= */ 4); diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/CacheAsserts.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/CacheAsserts.java index 3f20d466ed..cf2b246906 100644 --- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/CacheAsserts.java +++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/CacheAsserts.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertWithMessage; import android.net.Uri; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.UnstableApi; -import androidx.media3.common.util.Util; import androidx.media3.datasource.DataSource; import androidx.media3.datasource.DataSourceInputStream; import androidx.media3.datasource.DataSourceUtil; @@ -30,6 +29,7 @@ import androidx.media3.datasource.PlaceholderDataSource; import androidx.media3.datasource.cache.Cache; import androidx.media3.datasource.cache.CacheDataSource; import androidx.media3.test.utils.FakeDataSet.FakeData; +import com.google.common.io.ByteStreams; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.io.IOException; import java.util.ArrayList; @@ -158,7 +158,7 @@ public final class CacheAsserts { public static void assertReadData(DataSource dataSource, DataSpec dataSpec, byte[] expected) throws IOException { try (DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec)) { - byte[] bytes = Util.toByteArray(inputStream); + byte[] bytes = ByteStreams.toByteArray(inputStream); assertThat(bytes).isEqualTo(expected); } } diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/TestUtil.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/TestUtil.java index 079438016e..57f4355537 100644 --- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/TestUtil.java +++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/TestUtil.java @@ -36,7 +36,6 @@ import androidx.media3.common.MediaMetadata; import androidx.media3.common.StreamKey; import androidx.media3.common.Timeline; import androidx.media3.common.TrackGroup; -import androidx.media3.common.util.Assertions; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; import androidx.media3.database.DatabaseProvider; @@ -53,7 +52,9 @@ import androidx.media3.extractor.PositionHolder; import androidx.media3.extractor.SeekMap; import androidx.media3.extractor.metadata.MetadataInputBuffer; import com.google.common.collect.ImmutableList; +import com.google.common.io.ByteStreams; import com.google.common.primitives.Bytes; +import com.google.common.primitives.UnsignedBytes; import com.google.common.truth.Correspondence; import java.io.File; import java.io.FileInputStream; @@ -140,8 +141,7 @@ public class TestUtil { public static byte[] createByteArray(int... bytes) { byte[] array = new byte[bytes.length]; for (int i = 0; i < array.length; i++) { - Assertions.checkState(0x00 <= bytes[i] && bytes[i] <= 0xFF); - array[i] = (byte) bytes[i]; + array[i] = UnsignedBytes.checkedCast(bytes[i]); } return array; } @@ -202,14 +202,14 @@ public class TestUtil { /** Returns the bytes of an asset file. */ public static byte[] getByteArray(Context context, String fileName) throws IOException { try (InputStream inputStream = getInputStream(context, fileName)) { - return Util.toByteArray(inputStream); + return ByteStreams.toByteArray(inputStream); } } /** Returns the bytes of a file using its file path. */ public static byte[] getByteArrayFromFilePath(String filePath) throws IOException { try (InputStream inputStream = new FileInputStream(filePath)) { - return Util.toByteArray(inputStream); + return ByteStreams.toByteArray(inputStream); } }