package org.robolectric.shadows;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.TestRunners;
import java.io.FileDescriptor;
import java.util.HashMap;
import java.util.Map;
import static android.media.MediaMetadataRetriever.METADATA_KEY_ALBUM;
import static android.media.MediaMetadataRetriever.METADATA_KEY_ARTIST;
import static android.media.MediaMetadataRetriever.METADATA_KEY_TITLE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.robolectric.shadows.ShadowMediaMetadataRetriever.addException;
import static org.robolectric.shadows.ShadowMediaMetadataRetriever.addFrame;
import static org.robolectric.shadows.ShadowMediaMetadataRetriever.addMetadata;
import static org.robolectric.shadows.util.DataSource.toDataSource;
@RunWith(TestRunners.MultiApiSelfTest.class)
public class ShadowMediaMetadataRetrieverTest {
private final String path = "/media/foo.mp3";
private final String path2 = "/media/foo2.mp3";
private final MediaMetadataRetriever retriever = new MediaMetadataRetriever();
private final MediaMetadataRetriever retriever2 = new MediaMetadataRetriever();
private final Bitmap bitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
private final Bitmap bitmap2 = Bitmap.createBitmap(11, 11, Bitmap.Config.ARGB_8888);
private FileDescriptor fd = new FileDescriptor();
@Test
public void extractMetadata_shouldReturnValue() {
addMetadata(path, METADATA_KEY_ARTIST, "The Rolling Stones");
addMetadata(path, METADATA_KEY_ALBUM, "Sticky Fingers");
addMetadata(path, METADATA_KEY_TITLE, "Brown Sugar");
retriever.setDataSource(path);
assertThat(retriever.extractMetadata(METADATA_KEY_ARTIST)).isEqualTo("The Rolling Stones");
assertThat(retriever.extractMetadata(METADATA_KEY_ALBUM)).isEqualTo("Sticky Fingers");
assertThat(retriever.extractMetadata(METADATA_KEY_TITLE)).isEqualTo("Brown Sugar");
}
@Test
public void getFrameAtTime_shouldDependOnDataSource() {
addFrame(path, 1, bitmap);
addFrame(path2, 1, bitmap2);
retriever.setDataSource(path);
retriever2.setDataSource(path2);
assertThat(retriever.getFrameAtTime(1)).isEqualTo(bitmap);
assertThat(retriever.getFrameAtTime(1)).isNotEqualTo(bitmap2);
assertThat(retriever2.getFrameAtTime(1)).isEqualTo(bitmap2);
assertThat(retriever2.getFrameAtTime(1)).isNotEqualTo(bitmap);
}
@Test
public void setDataSource_usersSameDataSourceForFileDescriptors() {
addFrame(fd, 1, bitmap);
addFrame(fd, 0, 0, 1, bitmap2);
retriever.setDataSource(fd);
assertThat(retriever.getFrameAtTime(1)).isEqualTo(bitmap2);
}
@Test
public void setDataSource_fdsWithDifferentOffsetsAreDifferentDataSources() {
addFrame(fd, 1, bitmap);
addFrame(fd, 1, 0, 1, bitmap2);
retriever.setDataSource(fd);
retriever2.setDataSource(fd, 1, 0);
assertThat(retriever.getFrameAtTime(1)).isEqualTo(bitmap);
assertThat(retriever.getFrameAtTime(1)).isNotEqualTo(bitmap2);
assertThat(retriever2.getFrameAtTime(1)).isEqualTo(bitmap2);
assertThat(retriever2.getFrameAtTime(1)).isNotEqualTo(bitmap);
}
@Test
public void getFrameAtTime_shouldDependOnTime() {
Context context = RuntimeEnvironment.application;
Uri uri = Uri.parse(path);
addFrame(context, uri, 12, bitmap);
addFrame(context, uri, 13, bitmap2);
retriever.setDataSource(context, uri);
assertThat(retriever.getFrameAtTime(12)).isEqualTo(bitmap);
assertThat(retriever.getFrameAtTime(13)).isNotEqualTo(bitmap);
assertThat(retriever.getFrameAtTime(12)).isNotEqualTo(bitmap2);
assertThat(retriever.getFrameAtTime(13)).isEqualTo(bitmap2);
}
@Test
public void setDataSource_ignoresHeadersWhenShadowed() {
Context context = RuntimeEnvironment.application;
Uri uri = Uri.parse(path);
Map<String, String> headers = new HashMap<>();
headers.put("cookie", "nomnomnom");
retriever.setDataSource(context, uri);
retriever2.setDataSource(uri.toString(), headers);
addFrame(context, uri, 10, bitmap);
addFrame(uri.toString(), headers, 13, bitmap2);
assertThat(retriever.getFrameAtTime(10)).isEqualTo(bitmap);
assertThat(retriever.getFrameAtTime(13)).isEqualTo(bitmap2);
assertThat(retriever2.getFrameAtTime(13)).isEqualTo(bitmap2);
assertThat(retriever2.getFrameAtTime(10)).isEqualTo(bitmap);
}
@Test
public void reset_clearsStaticValues() {
addMetadata(path, METADATA_KEY_ARTIST, "The Rolling Stones");
addFrame(path, 1, bitmap);
addException(toDataSource(path2), new IllegalArgumentException());
retriever.setDataSource(path);
assertThat(retriever.extractMetadata(METADATA_KEY_ARTIST)).isEqualTo("The Rolling Stones");
assertThat(retriever.getFrameAtTime(1)).isSameAs(bitmap);
try {
retriever2.setDataSource(path2);
Assertions.failBecauseExceptionWasNotThrown(IllegalArgumentException.class);
} catch (IllegalArgumentException e) {}
ShadowMediaMetadataRetriever.reset();
assertThat(retriever.extractMetadata(METADATA_KEY_ARTIST)).isNull();
assertThat(retriever.getFrameAtTime(1)).isNull();
try {
retriever2.setDataSource(path2);
} catch (IllegalArgumentException e) {
Assertions.fail("Shouldn't throw exception after reset", e);
}
}
@Test
public void setDataSourceException_withAllowedException() {
RuntimeException e = new RuntimeException("some dummy message");
addException(toDataSource(path), e);
try {
retriever.setDataSource(path);
Assertions.failBecauseExceptionWasNotThrown(e.getClass());
} catch (Exception caught) {
assertThat(caught).isSameAs(e);
assertThat(e.getStackTrace()[0].getClassName())
.as("Stack trace should originate in Shadow")
.isEqualTo(ShadowMediaMetadataRetriever.class.getName());
}
}
}