diff options
author | 2024-01-29 23:29:34 +0000 | |
---|---|---|
committer | 2024-01-29 23:29:34 +0000 | |
commit | 2ed8d5176c3ca95e127bed919a1df5176e7c5c75 (patch) | |
tree | 3c7c81c7ad6ffc2cb062f4b0a81b574014e4616a | |
parent | 4c8a8d46e8186dcfa8029ef76ddcd6548c2a4662 (diff) | |
parent | 35f41b00fb9b8789e861b1a5e1b6ec8e32b72afa (diff) |
Merge "Expose radio metadata image query APIs as system APIs" into main
7 files changed, 82 insertions, 25 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 94cde98ca762..2c1f2fd0c1cd 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -6165,6 +6165,7 @@ package android.hardware.radio { method public boolean containsKey(String); method public int describeContents(); method @Deprecated public android.graphics.Bitmap getBitmap(String); + method @FlaggedApi("android.hardware.radio.hd_radio_improved") public int getBitmapId(@NonNull String); method public android.hardware.radio.RadioMetadata.Clock getClock(String); method public int getInt(String); method public String getString(String); @@ -6228,6 +6229,7 @@ package android.hardware.radio { method @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RADIO) public abstract void close(); method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RADIO) public abstract int getConfiguration(android.hardware.radio.RadioManager.BandConfig[]); method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RADIO) public android.hardware.radio.ProgramList getDynamicProgramList(@Nullable android.hardware.radio.ProgramList.Filter); + method @FlaggedApi("android.hardware.radio.hd_radio_improved") @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RADIO) public android.graphics.Bitmap getMetadataImage(int); method @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RADIO) public abstract boolean getMute(); method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RADIO) public java.util.Map<java.lang.String,java.lang.String> getParameters(@NonNull java.util.List<java.lang.String>); method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RADIO) public abstract int getProgramInformation(android.hardware.radio.RadioManager.ProgramInfo[]); diff --git a/core/java/android/hardware/radio/RadioMetadata.java b/core/java/android/hardware/radio/RadioMetadata.java index db14c08b3698..da6b9c25e2ba 100644 --- a/core/java/android/hardware/radio/RadioMetadata.java +++ b/core/java/android/hardware/radio/RadioMetadata.java @@ -507,10 +507,16 @@ public final class RadioMetadata implements Parcelable { * * @param key The key the value is stored under. * @return a bitmap identifier or 0 if it's missing. - * @hide This API is not thoroughly elaborated yet + * @throws NullPointerException if metadata key is {@code null} + * @throws IllegalArgumentException if the metadata with the key is not found in + * metadata or the key is not of bitmap-key type */ + @FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED) public int getBitmapId(@NonNull String key) { - if (!METADATA_KEY_ICON.equals(key) && !METADATA_KEY_ART.equals(key)) return 0; + Objects.requireNonNull(key, "Metadata key can not be null"); + if (!METADATA_KEY_ICON.equals(key) && !METADATA_KEY_ART.equals(key)) { + throw new IllegalArgumentException("Failed to retrieve key " + key + " as bitmap key"); + } return getInt(key); } diff --git a/core/java/android/hardware/radio/RadioTuner.java b/core/java/android/hardware/radio/RadioTuner.java index 9b2bcdea5f30..7c5c00369e93 100644 --- a/core/java/android/hardware/radio/RadioTuner.java +++ b/core/java/android/hardware/radio/RadioTuner.java @@ -17,6 +17,7 @@ package android.hardware.radio; import android.Manifest; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -332,29 +333,30 @@ public abstract class RadioTuner { public abstract int getProgramInformation(RadioManager.ProgramInfo[] info); /** - * Retrieves a {@link Bitmap} for the given image ID or null, + * Retrieves a {@link Bitmap} for the given image ID or throw {@link IllegalArgumentException}, * if the image was missing from the tuner. * * <p>This involves doing a call to the tuner, so the bitmap should be cached * on the application side. * - * <p>If the method returns null for non-zero ID, it means the image was - * updated on the tuner side. There is a race conditon between fetching - * image for an old ID and tuner updating the image (and cleaning up the + * <p>If the method throws {@link IllegalArgumentException} for non-zero ID, it + * means the image was updated on the tuner side. There is a race condition between + * fetching image for an old ID and tuner updating the image (and cleaning up the * old image). In such case, a new ProgramInfo with updated image id will * be sent with a {@link Callback#onProgramInfoChanged(RadioManager.ProgramInfo)} * callback. * * @param id The image identifier, retrieved with * {@link RadioMetadata#getBitmapId(String)}. - * @return A {@link Bitmap} or null. - * @throws IllegalArgumentException if id==0 - * @hide This API is not thoroughly elaborated yet + * @return A {@link Bitmap} for the given image ID. + * @throws IllegalArgumentException if id is 0 or the referenced image id no longer exists. */ - @SuppressWarnings("HiddenAbstractMethod") + @FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED) @RequiresPermission(Manifest.permission.ACCESS_BROADCAST_RADIO) - public abstract @Nullable Bitmap getMetadataImage(int id); - + public @NonNull Bitmap getMetadataImage(int id) { + throw new UnsupportedOperationException( + "Getting metadata image must be implemented in child classes"); + } /** * Initiates a background scan to update internally cached program list. * diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java index ba31ca3627bf..63b2d4cdd1fb 100644 --- a/core/java/android/hardware/radio/TunerAdapter.java +++ b/core/java/android/hardware/radio/TunerAdapter.java @@ -16,6 +16,7 @@ package android.hardware.radio; +import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Bitmap; import android.os.RemoteException; @@ -251,10 +252,18 @@ final class TunerAdapter extends RadioTuner { } @Override - @Nullable + @NonNull public Bitmap getMetadataImage(int id) { + if (id == 0) { + throw new IllegalArgumentException("Invalid metadata image id 0"); + } try { - return mTuner.getImage(id); + Bitmap bitmap = mTuner.getImage(id); + if (bitmap == null) { + throw new IllegalArgumentException("Metadata image with id " + id + + " is not available"); + } + return bitmap; } catch (RemoteException e) { throw new RuntimeException("Service died", e); } diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/DefaultRadioTunerTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/DefaultRadioTunerTest.java index 63de759282cf..ddf3615d24ed 100644 --- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/DefaultRadioTunerTest.java +++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/DefaultRadioTunerTest.java @@ -20,8 +20,6 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertThrows; -import android.graphics.Bitmap; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -88,12 +86,6 @@ public final class DefaultRadioTunerTest { return 0; } - @Nullable - @Override - public Bitmap getMetadataImage(int id) { - return null; - } - @Override public boolean startBackgroundScan() { return false; @@ -138,6 +130,16 @@ public final class DefaultRadioTunerTest { } @Test + public void getMetadataImage_forRadioTuner_throwsException() { + UnsupportedOperationException thrown = assertThrows(UnsupportedOperationException.class, + () -> DEFAULT_RADIO_TUNER.getMetadataImage(/* id= */ 1)); + + assertWithMessage("Exception for getting metadata image from default radio tuner") + .that(thrown).hasMessageThat() + .contains("Getting metadata image must be implemented in child classes"); + } + + @Test public void getDynamicProgramList_forRadioTuner_returnsNull() { assertWithMessage("Dynamic program list obtained from default radio tuner") .that(DEFAULT_RADIO_TUNER.getDynamicProgramList(new ProgramList.Filter())).isNull(); diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioMetadataTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioMetadataTest.java index fddfd397d068..b3a0aba0d352 100644 --- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioMetadataTest.java +++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioMetadataTest.java @@ -290,13 +290,29 @@ public final class RadioMetadataTest extends ExtendedRadioMockitoTestCase { } @Test - public void getBitmapId_withIllegalKey() { + public void getBitmapId_withIllegalKey_fails() { String illegalKey = RadioMetadata.METADATA_KEY_ARTIST; RadioMetadata metadata = mBuilder.putInt(RadioMetadata.METADATA_KEY_ART, INT_KEY_VALUE) .build(); - mExpect.withMessage("Bitmap id value with non-bitmap-id-type key %s", illegalKey) - .that(metadata.getBitmapId(illegalKey)).isEqualTo(0); + IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> { + metadata.getBitmapId(illegalKey); + }); + + mExpect.withMessage("Exception for getting string array for non-bitmap-id type key %s", + illegalKey).that(thrown).hasMessageThat().contains("bitmap key"); + } + + @Test + public void getBitmapId_withNullKey_fails() { + RadioMetadata metadata = mBuilder.build(); + + NullPointerException thrown = assertThrows(NullPointerException.class, () -> { + metadata.getBitmapId(/* key= */ null); + }); + + mExpect.withMessage("Exception for getting bitmap identifier with null key") + .that(thrown).hasMessageThat().contains("can not be null"); } @Test diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/TunerAdapterTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/TunerAdapterTest.java index 4cda26de2906..5aace81696cf 100644 --- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/TunerAdapterTest.java +++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/TunerAdapterTest.java @@ -514,6 +514,26 @@ public final class TunerAdapterTest { } @Test + public void getMetadataImage_withImageIdUnavailable_fails() throws Exception { + int nonExistImageId = 2; + when(mTunerMock.getImage(nonExistImageId)).thenReturn(null); + IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, + () -> mRadioTuner.getMetadataImage(nonExistImageId)); + + assertWithMessage("Exception for getting metadata image with non-existing id") + .that(thrown).hasMessageThat().contains("is not available"); + } + + @Test + public void getMetadataImage_withInvalidId_fails() { + IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, + () -> mRadioTuner.getMetadataImage(/* id= */ 0)); + + assertWithMessage("Exception for getting metadata image for id 0").that(thrown) + .hasMessageThat().contains("Invalid metadata image id 0"); + } + + @Test public void getMetadataImage_whenServiceDied_fails() throws Exception { when(mTunerMock.getImage(anyInt())).thenThrow(new RemoteException()); |