Commit 7411a31e by tonihei Committed by microkatz

Merge pull request #109 from tzugen:patch-1

PiperOrigin-RevId: 464045351
(cherry picked from commit 61e4f923)
parent 071f0a5a
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
small icon ([#104](https://github.com/androidx/media/issues/104)). small icon ([#104](https://github.com/androidx/media/issues/104)).
* Ensure commands sent before `MediaController.release()` are not dropped * Ensure commands sent before `MediaController.release()` are not dropped
([#99](https://github.com/androidx/media/issues/99)). ([#99](https://github.com/androidx/media/issues/99)).
* `SimpleBitmapLoader` can load bitmap from `file://` URIs
([#108](https://github.com/androidx/media/issues/108)).
* RTSP: * RTSP:
* Add H263 fragmented packet handling * Add H263 fragmented packet handling
([#119](https://github.com/androidx/media/pull/119)). ([#119](https://github.com/androidx/media/pull/119)).
......
...@@ -26,14 +26,19 @@ import androidx.test.core.app.ApplicationProvider; ...@@ -26,14 +26,19 @@ import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.MockWebServer;
import okio.Buffer; import okio.Buffer;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.function.ThrowingRunnable; import org.junit.function.ThrowingRunnable;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
/** /**
...@@ -47,6 +52,8 @@ public class SimpleBitmapLoaderTest { ...@@ -47,6 +52,8 @@ public class SimpleBitmapLoaderTest {
private static final String TEST_IMAGE_PATH = "media/jpeg/non-motion-photo-shortened.jpg"; private static final String TEST_IMAGE_PATH = "media/jpeg/non-motion-photo-shortened.jpg";
@Rule public final TemporaryFolder tempFolder = new TemporaryFolder();
@Test @Test
public void loadData() throws Exception { public void loadData() throws Exception {
SimpleBitmapLoader bitmapLoader = SimpleBitmapLoader bitmapLoader =
...@@ -70,11 +77,13 @@ public class SimpleBitmapLoaderTest { ...@@ -70,11 +77,13 @@ public class SimpleBitmapLoaderTest {
ListenableFuture<Bitmap> future = bitmapLoader.decodeBitmap(new byte[0]); ListenableFuture<Bitmap> future = bitmapLoader.decodeBitmap(new byte[0]);
assertException( assertException(
future::get, IllegalArgumentException.class, /* messagePart= */ "Could not decode bitmap"); future::get,
IllegalArgumentException.class,
/* messagePart= */ "Could not decode image data");
} }
@Test @Test
public void loadUri_loadsImage() throws Exception { public void load_httpUri_loadsImage() throws Exception {
SimpleBitmapLoader bitmapLoader = SimpleBitmapLoader bitmapLoader =
new SimpleBitmapLoader(MoreExecutors.newDirectExecutorService()); new SimpleBitmapLoader(MoreExecutors.newDirectExecutorService());
MockWebServer mockWebServer = new MockWebServer(); MockWebServer mockWebServer = new MockWebServer();
...@@ -93,7 +102,7 @@ public class SimpleBitmapLoaderTest { ...@@ -93,7 +102,7 @@ public class SimpleBitmapLoaderTest {
} }
@Test @Test
public void loadUri_serverError_throwsException() { public void load_httpUriAndServerError_throwsException() {
SimpleBitmapLoader bitmapLoader = SimpleBitmapLoader bitmapLoader =
new SimpleBitmapLoader(MoreExecutors.newDirectExecutorService()); new SimpleBitmapLoader(MoreExecutors.newDirectExecutorService());
MockWebServer mockWebServer = new MockWebServer(); MockWebServer mockWebServer = new MockWebServer();
...@@ -106,7 +115,36 @@ public class SimpleBitmapLoaderTest { ...@@ -106,7 +115,36 @@ public class SimpleBitmapLoaderTest {
} }
@Test @Test
public void loadUri_nonHttpUri_throwsException() { public void load_fileUri_loadsImage() throws Exception {
byte[] imageData =
TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), TEST_IMAGE_PATH);
File file = tempFolder.newFile();
Files.write(Paths.get(file.getAbsolutePath()), imageData);
Uri uri = Uri.fromFile(file);
SimpleBitmapLoader bitmapLoader =
new SimpleBitmapLoader(MoreExecutors.newDirectExecutorService());
Bitmap bitmap = bitmapLoader.loadBitmap(uri).get();
assertThat(
bitmap.sameAs(
BitmapFactory.decodeByteArray(imageData, /* offset= */ 0, imageData.length)))
.isTrue();
}
@Test
public void fileUriWithFileNotExisting() throws Exception {
SimpleBitmapLoader bitmapLoader =
new SimpleBitmapLoader(MoreExecutors.newDirectExecutorService());
assertException(
() -> bitmapLoader.loadBitmap(Uri.parse("file:///not_valid/path/image.bmp")).get(),
IllegalArgumentException.class,
/* messagePart= */ "Could not read image from file");
}
@Test
public void load_unhandledUriScheme_throwsException() {
SimpleBitmapLoader bitmapLoader = SimpleBitmapLoader bitmapLoader =
new SimpleBitmapLoader(MoreExecutors.newDirectExecutorService()); new SimpleBitmapLoader(MoreExecutors.newDirectExecutorService());
...@@ -115,10 +153,6 @@ public class SimpleBitmapLoaderTest { ...@@ -115,10 +153,6 @@ public class SimpleBitmapLoaderTest {
MalformedURLException.class, MalformedURLException.class,
/* messagePart= */ "no protocol"); /* messagePart= */ "no protocol");
assertException( assertException(
() -> bitmapLoader.loadBitmap(Uri.parse("file://local/path")).get(),
UnsupportedOperationException.class,
/* messagePart= */ "Unsupported scheme");
assertException(
() -> bitmapLoader.loadBitmap(Uri.parse("asset://asset/path")).get(), () -> bitmapLoader.loadBitmap(Uri.parse("asset://asset/path")).get(),
MalformedURLException.class, MalformedURLException.class,
/* messagePart= */ "unknown protocol"); /* messagePart= */ "unknown protocol");
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package androidx.media3.session; package androidx.media3.session;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkStateNotNull; import static androidx.media3.common.util.Assertions.checkStateNotNull;
import android.graphics.Bitmap; import android.graphics.Bitmap;
...@@ -38,19 +39,21 @@ import java.util.concurrent.Executors; ...@@ -38,19 +39,21 @@ import java.util.concurrent.Executors;
/** /**
* A simple bitmap loader that delegates all tasks to an executor and supports fetching images from * A simple bitmap loader that delegates all tasks to an executor and supports fetching images from
* HTTP/HTTPS endpoints. * URIs with {@code file}, {@code http} and {@code https} schemes.
* *
* <p>Loading tasks are delegated to an {@link ExecutorService} (or {@link * <p>Loading tasks are delegated to an {@link ExecutorService} (or {@link
* ListeningExecutorService}) defined during construction. If no executor service is defined, all * ListeningExecutorService}) defined during construction. If no executor service is defined, all
* tasks are delegated to a single-thread executor service that is shared between instances of this * tasks are delegated to a single-thread executor service that is shared between instances of this
* class. * class.
* *
* <p>The supported URI scheme is only HTTP/HTTPS and this class reads a resource only when the * <p>For HTTP(S) transfers, this class reads a resource only when the endpoint responds with an
* endpoint responds with an {@code HTTP 200} after sending the HTTP request. * {@code HTTP 200} after sending the HTTP request.
*/ */
@UnstableApi @UnstableApi
public final class SimpleBitmapLoader implements BitmapLoader { public final class SimpleBitmapLoader implements BitmapLoader {
private static final String FILE_URI_EXCEPTION_MESSAGE = "Could not read image from file";
private static final Supplier<ListeningExecutorService> DEFAULT_EXECUTOR_SERVICE = private static final Supplier<ListeningExecutorService> DEFAULT_EXECUTOR_SERVICE =
Suppliers.memoize( Suppliers.memoize(
() -> MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor())); () -> MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
...@@ -82,13 +85,22 @@ public final class SimpleBitmapLoader implements BitmapLoader { ...@@ -82,13 +85,22 @@ public final class SimpleBitmapLoader implements BitmapLoader {
private static Bitmap decode(byte[] data) { private static Bitmap decode(byte[] data) {
@Nullable Bitmap bitmap = BitmapFactory.decodeByteArray(data, /* offset= */ 0, data.length); @Nullable Bitmap bitmap = BitmapFactory.decodeByteArray(data, /* offset= */ 0, data.length);
if (bitmap == null) { checkArgument(bitmap != null, "Could not decode image data");
throw new IllegalArgumentException("Could not decode bitmap");
}
return bitmap; return bitmap;
} }
private static Bitmap load(Uri uri) throws IOException { private static Bitmap load(Uri uri) throws IOException {
if ("file".equals(uri.getScheme())) {
@Nullable String path = uri.getPath();
if (path == null) {
throw new IllegalArgumentException(FILE_URI_EXCEPTION_MESSAGE);
}
@Nullable Bitmap bitmap = BitmapFactory.decodeFile(path);
if (bitmap == null) {
throw new IllegalArgumentException(FILE_URI_EXCEPTION_MESSAGE);
}
return bitmap;
}
URLConnection connection = new URL(uri.toString()).openConnection(); URLConnection connection = new URL(uri.toString()).openConnection();
if (!(connection instanceof HttpURLConnection)) { if (!(connection instanceof HttpURLConnection)) {
throw new UnsupportedOperationException("Unsupported scheme: " + uri.getScheme()); throw new UnsupportedOperationException("Unsupported scheme: " + uri.getScheme());
......
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