Commit fde3075a by samrobinson Committed by Ian Baker

Add an artworkDataType to MediaMetadata.

This field is to be associated with the artworkData.

PiperOrigin-RevId: 385757480
parent 0fe504d4
...@@ -49,6 +49,7 @@ public final class MediaMetadata implements Bundleable { ...@@ -49,6 +49,7 @@ public final class MediaMetadata implements Bundleable {
@Nullable private Rating userRating; @Nullable private Rating userRating;
@Nullable private Rating overallRating; @Nullable private Rating overallRating;
@Nullable private byte[] artworkData; @Nullable private byte[] artworkData;
@Nullable @PictureType private Integer artworkDataType;
@Nullable private Uri artworkUri; @Nullable private Uri artworkUri;
@Nullable private Integer trackNumber; @Nullable private Integer trackNumber;
@Nullable private Integer totalTrackCount; @Nullable private Integer totalTrackCount;
...@@ -83,6 +84,7 @@ public final class MediaMetadata implements Bundleable { ...@@ -83,6 +84,7 @@ public final class MediaMetadata implements Bundleable {
this.userRating = mediaMetadata.userRating; this.userRating = mediaMetadata.userRating;
this.overallRating = mediaMetadata.overallRating; this.overallRating = mediaMetadata.overallRating;
this.artworkData = mediaMetadata.artworkData; this.artworkData = mediaMetadata.artworkData;
this.artworkDataType = mediaMetadata.artworkDataType;
this.artworkUri = mediaMetadata.artworkUri; this.artworkUri = mediaMetadata.artworkUri;
this.trackNumber = mediaMetadata.trackNumber; this.trackNumber = mediaMetadata.trackNumber;
this.totalTrackCount = mediaMetadata.totalTrackCount; this.totalTrackCount = mediaMetadata.totalTrackCount;
...@@ -168,9 +170,41 @@ public final class MediaMetadata implements Bundleable { ...@@ -168,9 +170,41 @@ public final class MediaMetadata implements Bundleable {
return this; return this;
} }
/** Sets the artwork data as a compressed byte array. */ /**
* @deprecated Use {@link #setArtworkData(byte[] data, Integer pictureType)} or {@link
* #maybeSetArtworkData(byte[] data, int pictureType)}, providing a {@link PictureType}.
*/
@Deprecated
public Builder setArtworkData(@Nullable byte[] artworkData) { public Builder setArtworkData(@Nullable byte[] artworkData) {
return setArtworkData(artworkData, /* artworkDataType= */ null);
}
/**
* Sets the artwork data as a compressed byte array with an associated {@link PictureType
* artworkDataType}.
*/
public Builder setArtworkData(
@Nullable byte[] artworkData, @Nullable @PictureType Integer artworkDataType) {
this.artworkData = artworkData == null ? null : artworkData.clone(); this.artworkData = artworkData == null ? null : artworkData.clone();
this.artworkDataType = artworkDataType;
return this;
}
/**
* Sets the artwork data as a compressed byte array in the event that the associated {@link
* PictureType} is {@link #PICTURE_TYPE_FRONT_COVER}, the existing {@link PictureType} is not
* {@link #PICTURE_TYPE_FRONT_COVER}, or the current artworkData is not set.
*
* <p>Use {@link #setArtworkData(byte[], Integer)} to set the artwork data without checking the
* {@link PictureType}.
*/
public Builder maybeSetArtworkData(byte[] artworkData, @PictureType int artworkDataType) {
if (this.artworkData == null
|| Util.areEqual(artworkDataType, PICTURE_TYPE_FRONT_COVER)
|| !Util.areEqual(this.artworkDataType, PICTURE_TYPE_FRONT_COVER)) {
this.artworkData = artworkData.clone();
this.artworkDataType = artworkDataType;
}
return this; return this;
} }
...@@ -393,6 +427,61 @@ public final class MediaMetadata implements Bundleable { ...@@ -393,6 +427,61 @@ public final class MediaMetadata implements Bundleable {
/** Type for a folder containing media categorized by year. */ /** Type for a folder containing media categorized by year. */
public static final int FOLDER_TYPE_YEARS = 6; public static final int FOLDER_TYPE_YEARS = 6;
/**
* The picture type of the artwork.
*
* <p>Values sourced from the ID3 v2.4 specification (See section 4.14 of
* https://id3.org/id3v2.4.0-frames).
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@IntDef({
PICTURE_TYPE_OTHER,
PICTURE_TYPE_FILE_ICON,
PICTURE_TYPE_FILE_ICON_OTHER,
PICTURE_TYPE_FRONT_COVER,
PICTURE_TYPE_BACK_COVER,
PICTURE_TYPE_LEAFLET_PAGE,
PICTURE_TYPE_MEDIA,
PICTURE_TYPE_LEAD_ARTIST_PERFORMER,
PICTURE_TYPE_ARTIST_PERFORMER,
PICTURE_TYPE_CONDUCTOR,
PICTURE_TYPE_BAND_ORCHESTRA,
PICTURE_TYPE_COMPOSER,
PICTURE_TYPE_LYRICIST,
PICTURE_TYPE_RECORDING_LOCATION,
PICTURE_TYPE_DURING_RECORDING,
PICTURE_TYPE_DURING_PERFORMANCE,
PICTURE_TYPE_MOVIE_VIDEO_SCREEN_CAPTURE,
PICTURE_TYPE_A_BRIGHT_COLORED_FISH,
PICTURE_TYPE_ILLUSTRATION,
PICTURE_TYPE_BAND_ARTIST_LOGO,
PICTURE_TYPE_PUBLISHER_STUDIO_LOGO
})
public @interface PictureType {}
public static final int PICTURE_TYPE_OTHER = 0x00;
public static final int PICTURE_TYPE_FILE_ICON = 0x01;
public static final int PICTURE_TYPE_FILE_ICON_OTHER = 0x02;
public static final int PICTURE_TYPE_FRONT_COVER = 0x03;
public static final int PICTURE_TYPE_BACK_COVER = 0x04;
public static final int PICTURE_TYPE_LEAFLET_PAGE = 0x05;
public static final int PICTURE_TYPE_MEDIA = 0x06;
public static final int PICTURE_TYPE_LEAD_ARTIST_PERFORMER = 0x07;
public static final int PICTURE_TYPE_ARTIST_PERFORMER = 0x08;
public static final int PICTURE_TYPE_CONDUCTOR = 0x09;
public static final int PICTURE_TYPE_BAND_ORCHESTRA = 0x0A;
public static final int PICTURE_TYPE_COMPOSER = 0x0B;
public static final int PICTURE_TYPE_LYRICIST = 0x0C;
public static final int PICTURE_TYPE_RECORDING_LOCATION = 0x0D;
public static final int PICTURE_TYPE_DURING_RECORDING = 0x0E;
public static final int PICTURE_TYPE_DURING_PERFORMANCE = 0x0F;
public static final int PICTURE_TYPE_MOVIE_VIDEO_SCREEN_CAPTURE = 0x10;
public static final int PICTURE_TYPE_A_BRIGHT_COLORED_FISH = 0x11;
public static final int PICTURE_TYPE_ILLUSTRATION = 0x12;
public static final int PICTURE_TYPE_BAND_ARTIST_LOGO = 0x13;
public static final int PICTURE_TYPE_PUBLISHER_STUDIO_LOGO = 0x14;
/** Empty {@link MediaMetadata}. */ /** Empty {@link MediaMetadata}. */
public static final MediaMetadata EMPTY = new MediaMetadata.Builder().build(); public static final MediaMetadata EMPTY = new MediaMetadata.Builder().build();
...@@ -422,6 +511,8 @@ public final class MediaMetadata implements Bundleable { ...@@ -422,6 +511,8 @@ public final class MediaMetadata implements Bundleable {
@Nullable public final Rating overallRating; @Nullable public final Rating overallRating;
/** Optional artwork data as a compressed byte array. */ /** Optional artwork data as a compressed byte array. */
@Nullable public final byte[] artworkData; @Nullable public final byte[] artworkData;
/** Optional {@link PictureType} of the artwork data. */
@Nullable @PictureType public final Integer artworkDataType;
/** Optional artwork {@link Uri}. */ /** Optional artwork {@link Uri}. */
@Nullable public final Uri artworkUri; @Nullable public final Uri artworkUri;
/** Optional track number. */ /** Optional track number. */
...@@ -498,6 +589,7 @@ public final class MediaMetadata implements Bundleable { ...@@ -498,6 +589,7 @@ public final class MediaMetadata implements Bundleable {
this.userRating = builder.userRating; this.userRating = builder.userRating;
this.overallRating = builder.overallRating; this.overallRating = builder.overallRating;
this.artworkData = builder.artworkData; this.artworkData = builder.artworkData;
this.artworkDataType = builder.artworkDataType;
this.artworkUri = builder.artworkUri; this.artworkUri = builder.artworkUri;
this.trackNumber = builder.trackNumber; this.trackNumber = builder.trackNumber;
this.totalTrackCount = builder.totalTrackCount; this.totalTrackCount = builder.totalTrackCount;
...@@ -545,6 +637,7 @@ public final class MediaMetadata implements Bundleable { ...@@ -545,6 +637,7 @@ public final class MediaMetadata implements Bundleable {
&& Util.areEqual(userRating, that.userRating) && Util.areEqual(userRating, that.userRating)
&& Util.areEqual(overallRating, that.overallRating) && Util.areEqual(overallRating, that.overallRating)
&& Arrays.equals(artworkData, that.artworkData) && Arrays.equals(artworkData, that.artworkData)
&& Util.areEqual(artworkDataType, that.artworkDataType)
&& Util.areEqual(artworkUri, that.artworkUri) && Util.areEqual(artworkUri, that.artworkUri)
&& Util.areEqual(trackNumber, that.trackNumber) && Util.areEqual(trackNumber, that.trackNumber)
&& Util.areEqual(totalTrackCount, that.totalTrackCount) && Util.areEqual(totalTrackCount, that.totalTrackCount)
...@@ -579,6 +672,7 @@ public final class MediaMetadata implements Bundleable { ...@@ -579,6 +672,7 @@ public final class MediaMetadata implements Bundleable {
userRating, userRating,
overallRating, overallRating,
Arrays.hashCode(artworkData), Arrays.hashCode(artworkData),
artworkDataType,
artworkUri, artworkUri,
trackNumber, trackNumber,
totalTrackCount, totalTrackCount,
...@@ -615,6 +709,7 @@ public final class MediaMetadata implements Bundleable { ...@@ -615,6 +709,7 @@ public final class MediaMetadata implements Bundleable {
FIELD_USER_RATING, FIELD_USER_RATING,
FIELD_OVERALL_RATING, FIELD_OVERALL_RATING,
FIELD_ARTWORK_DATA, FIELD_ARTWORK_DATA,
FIELD_ARTWORK_DATA_TYPE,
FIELD_ARTWORK_URI, FIELD_ARTWORK_URI,
FIELD_TRACK_NUMBER, FIELD_TRACK_NUMBER,
FIELD_TOTAL_TRACK_COUNT, FIELD_TOTAL_TRACK_COUNT,
...@@ -666,6 +761,7 @@ public final class MediaMetadata implements Bundleable { ...@@ -666,6 +761,7 @@ public final class MediaMetadata implements Bundleable {
private static final int FIELD_TOTAL_DISC_COUNT = 26; private static final int FIELD_TOTAL_DISC_COUNT = 26;
private static final int FIELD_GENRE = 27; private static final int FIELD_GENRE = 27;
private static final int FIELD_COMPILATION = 28; private static final int FIELD_COMPILATION = 28;
private static final int FIELD_ARTWORK_DATA_TYPE = 29;
private static final int FIELD_EXTRAS = 1000; private static final int FIELD_EXTRAS = 1000;
@Override @Override
...@@ -729,6 +825,9 @@ public final class MediaMetadata implements Bundleable { ...@@ -729,6 +825,9 @@ public final class MediaMetadata implements Bundleable {
if (totalDiscCount != null) { if (totalDiscCount != null) {
bundle.putInt(keyForField(FIELD_TOTAL_DISC_COUNT), totalDiscCount); bundle.putInt(keyForField(FIELD_TOTAL_DISC_COUNT), totalDiscCount);
} }
if (artworkDataType != null) {
bundle.putInt(keyForField(FIELD_ARTWORK_DATA_TYPE), artworkDataType);
}
if (extras != null) { if (extras != null) {
bundle.putBundle(keyForField(FIELD_EXTRAS), extras); bundle.putBundle(keyForField(FIELD_EXTRAS), extras);
} }
...@@ -749,7 +848,11 @@ public final class MediaMetadata implements Bundleable { ...@@ -749,7 +848,11 @@ public final class MediaMetadata implements Bundleable {
.setSubtitle(bundle.getCharSequence(keyForField(FIELD_SUBTITLE))) .setSubtitle(bundle.getCharSequence(keyForField(FIELD_SUBTITLE)))
.setDescription(bundle.getCharSequence(keyForField(FIELD_DESCRIPTION))) .setDescription(bundle.getCharSequence(keyForField(FIELD_DESCRIPTION)))
.setMediaUri(bundle.getParcelable(keyForField(FIELD_MEDIA_URI))) .setMediaUri(bundle.getParcelable(keyForField(FIELD_MEDIA_URI)))
.setArtworkData(bundle.getByteArray(keyForField(FIELD_ARTWORK_DATA))) .setArtworkData(
bundle.getByteArray(keyForField(FIELD_ARTWORK_DATA)),
bundle.containsKey(keyForField(FIELD_ARTWORK_DATA_TYPE))
? bundle.getInt(keyForField(FIELD_ARTWORK_DATA_TYPE))
: null)
.setArtworkUri(bundle.getParcelable(keyForField(FIELD_ARTWORK_URI))) .setArtworkUri(bundle.getParcelable(keyForField(FIELD_ARTWORK_URI)))
.setWriter(bundle.getCharSequence(keyForField(FIELD_WRITER))) .setWriter(bundle.getCharSequence(keyForField(FIELD_WRITER)))
.setComposer(bundle.getCharSequence(keyForField(FIELD_COMPOSER))) .setComposer(bundle.getCharSequence(keyForField(FIELD_COMPOSER)))
......
...@@ -76,7 +76,7 @@ public final class PictureFrame implements Metadata.Entry { ...@@ -76,7 +76,7 @@ public final class PictureFrame implements Metadata.Entry {
@Override @Override
public void populateMediaMetadata(MediaMetadata.Builder builder) { public void populateMediaMetadata(MediaMetadata.Builder builder) {
builder.setArtworkData(pictureData); builder.maybeSetArtworkData(pictureData, pictureType);
} }
@Override @Override
......
...@@ -53,7 +53,7 @@ public final class ApicFrame extends Id3Frame { ...@@ -53,7 +53,7 @@ public final class ApicFrame extends Id3Frame {
@Override @Override
public void populateMediaMetadata(MediaMetadata.Builder builder) { public void populateMediaMetadata(MediaMetadata.Builder builder) {
builder.setArtworkData(pictureData); builder.maybeSetArtworkData(pictureData, pictureType);
} }
@Override @Override
......
...@@ -20,10 +20,10 @@ import static com.google.common.truth.Truth.assertThat; ...@@ -20,10 +20,10 @@ import static com.google.common.truth.Truth.assertThat;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.MediaMetadata.PictureType;
import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.id3.ApicFrame; import com.google.android.exoplayer2.metadata.id3.ApicFrame;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import java.util.Arrays;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
...@@ -46,6 +46,7 @@ public class MediaMetadataTest { ...@@ -46,6 +46,7 @@ public class MediaMetadataTest {
assertThat(mediaMetadata.userRating).isNull(); assertThat(mediaMetadata.userRating).isNull();
assertThat(mediaMetadata.overallRating).isNull(); assertThat(mediaMetadata.overallRating).isNull();
assertThat(mediaMetadata.artworkData).isNull(); assertThat(mediaMetadata.artworkData).isNull();
assertThat(mediaMetadata.artworkDataType).isNull();
assertThat(mediaMetadata.artworkUri).isNull(); assertThat(mediaMetadata.artworkUri).isNull();
assertThat(mediaMetadata.trackNumber).isNull(); assertThat(mediaMetadata.trackNumber).isNull();
assertThat(mediaMetadata.totalTrackCount).isNull(); assertThat(mediaMetadata.totalTrackCount).isNull();
...@@ -79,9 +80,10 @@ public class MediaMetadataTest { ...@@ -79,9 +80,10 @@ public class MediaMetadataTest {
@Test @Test
public void builderSetArtworkData_setsArtworkData() { public void builderSetArtworkData_setsArtworkData() {
byte[] bytes = new byte[] {35, 12, 6, 77}; byte[] bytes = new byte[] {35, 12, 6, 77};
MediaMetadata mediaMetadata = new MediaMetadata.Builder().setArtworkData(bytes).build(); MediaMetadata mediaMetadata =
new MediaMetadata.Builder().setArtworkData(new byte[] {35, 12, 6, 77}, null).build();
assertThat(Arrays.equals(mediaMetadata.artworkData, bytes)).isTrue(); assertThat(mediaMetadata.artworkData).isEqualTo(bytes);
} }
@Test @Test
...@@ -104,7 +106,8 @@ public class MediaMetadataTest { ...@@ -104,7 +106,8 @@ public class MediaMetadataTest {
.setMediaUri(Uri.parse("https://www.google.com")) .setMediaUri(Uri.parse("https://www.google.com"))
.setUserRating(new HeartRating(false)) .setUserRating(new HeartRating(false))
.setOverallRating(new PercentageRating(87.4f)) .setOverallRating(new PercentageRating(87.4f))
.setArtworkData(new byte[] {-88, 12, 3, 2, 124, -54, -33, 69}) .setArtworkData(
new byte[] {-88, 12, 3, 2, 124, -54, -33, 69}, MediaMetadata.PICTURE_TYPE_MEDIA)
.setTrackNumber(4) .setTrackNumber(4)
.setTotalTrackCount(12) .setTotalTrackCount(12)
.setFolderType(MediaMetadata.FOLDER_TYPE_PLAYLISTS) .setFolderType(MediaMetadata.FOLDER_TYPE_PLAYLISTS)
...@@ -133,11 +136,12 @@ public class MediaMetadataTest { ...@@ -133,11 +136,12 @@ public class MediaMetadataTest {
@Test @Test
public void builderPopulatedFromApicFrameEntry_setsArtwork() { public void builderPopulatedFromApicFrameEntry_setsArtwork() {
byte[] pictureData = new byte[] {-12, 52, 33, 85, 34, 22, 1, -55}; byte[] pictureData = new byte[] {-12, 52, 33, 85, 34, 22, 1, -55};
@PictureType int pictureType = MediaMetadata.PICTURE_TYPE_LEAFLET_PAGE;
Metadata.Entry entry = Metadata.Entry entry =
new ApicFrame( new ApicFrame(
/* mimeType= */ MimeTypes.BASE_TYPE_IMAGE, /* mimeType= */ MimeTypes.BASE_TYPE_IMAGE,
/* description= */ "an image", /* description= */ "an image",
/* pictureType= */ 0x03, pictureType,
pictureData); pictureData);
MediaMetadata.Builder builder = MediaMetadata.EMPTY.buildUpon(); MediaMetadata.Builder builder = MediaMetadata.EMPTY.buildUpon();
...@@ -145,5 +149,65 @@ public class MediaMetadataTest { ...@@ -145,5 +149,65 @@ public class MediaMetadataTest {
MediaMetadata mediaMetadata = builder.build(); MediaMetadata mediaMetadata = builder.build();
assertThat(mediaMetadata.artworkData).isEqualTo(pictureData); assertThat(mediaMetadata.artworkData).isEqualTo(pictureData);
assertThat(mediaMetadata.artworkDataType).isEqualTo(pictureType);
}
@Test
public void builderPopulatedFromApicFrameEntry_considersTypePriority() {
byte[] data1 = new byte[] {1, 1, 1, 1};
Metadata.Entry entry1 =
new ApicFrame(
/* mimeType= */ MimeTypes.BASE_TYPE_IMAGE,
/* description= */ "an image",
MediaMetadata.PICTURE_TYPE_BAND_ARTIST_LOGO,
data1);
byte[] data2 = new byte[] {2, 2, 2, 2};
Metadata.Entry entry2 =
new ApicFrame(
/* mimeType= */ MimeTypes.BASE_TYPE_IMAGE,
/* description= */ "an image",
MediaMetadata.PICTURE_TYPE_ARTIST_PERFORMER,
data2);
byte[] data3 = new byte[] {3, 3, 3, 3};
Metadata.Entry entry3 =
new ApicFrame(
/* mimeType= */ MimeTypes.BASE_TYPE_IMAGE,
/* description= */ "an image",
MediaMetadata.PICTURE_TYPE_FRONT_COVER,
data3);
byte[] data4 = new byte[] {4, 4, 4, 4};
Metadata.Entry entry4 =
new ApicFrame(
/* mimeType= */ MimeTypes.BASE_TYPE_IMAGE,
/* description= */ "an image",
MediaMetadata.PICTURE_TYPE_ILLUSTRATION,
data4);
byte[] data5 = new byte[] {5, 5, 5, 5};
Metadata.Entry entry5 =
new ApicFrame(
/* mimeType= */ MimeTypes.BASE_TYPE_IMAGE,
/* description= */ "an image",
MediaMetadata.PICTURE_TYPE_FRONT_COVER,
data5);
MediaMetadata.Builder builder = MediaMetadata.EMPTY.buildUpon();
entry1.populateMediaMetadata(builder);
assertThat(builder.build().artworkData).isEqualTo(data1);
// Data updates when any type is given, if the current type is not front cover.
entry2.populateMediaMetadata(builder);
assertThat(builder.build().artworkData).isEqualTo(data2);
// Data updates because this entry picture type is front cover.
entry3.populateMediaMetadata(builder);
assertThat(builder.build().artworkData).isEqualTo(data3);
// Data does not update because the current type is front cover, and this entry type is not.
entry4.populateMediaMetadata(builder);
assertThat(builder.build().artworkData).isEqualTo(data3);
// Data updates because this entry picture type is front cover.
entry5.populateMediaMetadata(builder);
assertThat(builder.build().artworkData).isEqualTo(data5);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment