summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--car-broadcastradio-support/Android.bp9
-rw-r--r--car-broadcastradio-support/TEST_MAPPING7
-rw-r--r--car-broadcastradio-support/src/com/android/car/broadcastradio/support/Program.java5
-rw-r--r--car-broadcastradio-support/src/com/android/car/broadcastradio/support/media/BrowseTree.java46
-rw-r--r--car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ImageResolver.java3
-rw-r--r--car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ProgramInfoExt.java89
-rw-r--r--car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ProgramSelectorExt.java18
-rw-r--r--car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/RadioMetadataExt.java13
-rw-r--r--car-broadcastradio-support/tests/Android.bp42
-rw-r--r--car-broadcastradio-support/tests/AndroidManifest.xml29
-rw-r--r--car-broadcastradio-support/tests/src/com/android/car/broadcastradio/support/platform/ProgramInfoExtTest.java203
-rw-r--r--car-broadcastradio-support/tests/src/com/android/car/broadcastradio/support/platform/ProgramSelectorExtTest.java356
12 files changed, 742 insertions, 78 deletions
diff --git a/car-broadcastradio-support/Android.bp b/car-broadcastradio-support/Android.bp
index 007a65f..64647bc 100644
--- a/car-broadcastradio-support/Android.bp
+++ b/car-broadcastradio-support/Android.bp
@@ -35,4 +35,13 @@ android_library {
dist: {
targets: ["dist_files"],
},
+
+ static_libs: [
+ "androidx.legacy_legacy-support-v4",
+ ],
+
+ libs: ["android.car-system-stubs"],
+ min_sdk_version: "33",
+ target_sdk_version: "33",
+ sdk_version: "system_current",
}
diff --git a/car-broadcastradio-support/TEST_MAPPING b/car-broadcastradio-support/TEST_MAPPING
new file mode 100644
index 0000000..26e1961
--- /dev/null
+++ b/car-broadcastradio-support/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "CarBroadcastRadioSupportTests"
+ }
+ ]
+}
diff --git a/car-broadcastradio-support/src/com/android/car/broadcastradio/support/Program.java b/car-broadcastradio-support/src/com/android/car/broadcastradio/support/Program.java
index af57c90..21f3cdf 100644
--- a/car-broadcastradio-support/src/com/android/car/broadcastradio/support/Program.java
+++ b/car-broadcastradio-support/src/com/android/car/broadcastradio/support/Program.java
@@ -16,14 +16,15 @@
package com.android.car.broadcastradio.support;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.graphics.Bitmap;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager.ProgramInfo;
import android.os.Parcel;
import android.os.Parcelable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import com.android.car.broadcastradio.support.platform.ProgramInfoExt;
import java.util.Objects;
diff --git a/car-broadcastradio-support/src/com/android/car/broadcastradio/support/media/BrowseTree.java b/car-broadcastradio-support/src/com/android/car/broadcastradio/support/media/BrowseTree.java
index 39d23dc..4d6624b 100644
--- a/car-broadcastradio-support/src/com/android/car/broadcastradio/support/media/BrowseTree.java
+++ b/car-broadcastradio-support/src/com/android/car/broadcastradio/support/media/BrowseTree.java
@@ -16,23 +16,24 @@
package com.android.car.broadcastradio.support.media;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.StringRes;
import android.graphics.Bitmap;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioManager.BandDescriptor;
import android.hardware.radio.RadioMetadata;
-import android.media.MediaDescription;
-import android.media.browse.MediaBrowser.MediaItem;
import android.os.Bundle;
-import android.service.media.MediaBrowserService;
-import android.service.media.MediaBrowserService.BrowserRoot;
-import android.service.media.MediaBrowserService.Result;
+import android.support.v4.media.MediaBrowserCompat.MediaItem;
+import android.support.v4.media.MediaDescriptionCompat;
import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+import androidx.media.MediaBrowserServiceCompat;
+import androidx.media.MediaBrowserServiceCompat.BrowserRoot;
+import androidx.media.MediaBrowserServiceCompat.Result;
+
import com.android.car.broadcastradio.support.Program;
import com.android.car.broadcastradio.support.R;
import com.android.car.broadcastradio.support.platform.ImageResolver;
@@ -133,7 +134,7 @@ public class BrowseTree {
private final BrowserRoot mRoot = new BrowserRoot(NODE_ROOT, null);
private final Object mLock = new Object();
- private final @NonNull MediaBrowserService mBrowserService;
+ private final @NonNull MediaBrowserServiceCompat mBrowserService;
private final @Nullable ImageResolver mImageResolver;
private List<MediaItem> mRootChildren;
@@ -155,7 +156,7 @@ public class BrowseTree {
@Nullable Set<Program> mFavorites;
@Nullable private List<MediaItem> mFavoritesCache;
- public BrowseTree(@NonNull MediaBrowserService browserService,
+ public BrowseTree(@NonNull MediaBrowserServiceCompat browserService,
@Nullable ImageResolver imageResolver) {
mBrowserService = Objects.requireNonNull(browserService);
mImageResolver = imageResolver;
@@ -165,9 +166,10 @@ public class BrowseTree {
return mRoot;
}
- private static MediaItem createChild(MediaDescription.Builder descBuilder,
- String mediaId, String title, ProgramSelector sel, Bitmap icon) {
- MediaDescription desc = descBuilder
+ private static MediaItem createChild(
+ MediaDescriptionCompat.Builder descBuilder, String mediaId, String title,
+ ProgramSelector sel, Bitmap icon) {
+ MediaDescriptionCompat desc = descBuilder
.setMediaId(mediaId)
.setMediaUri(ProgramSelectorExt.toUri(sel))
.setTitle(title)
@@ -176,13 +178,13 @@ public class BrowseTree {
return new MediaItem(desc, MediaItem.FLAG_PLAYABLE);
}
- private static MediaItem createFolder(MediaDescription.Builder descBuilder, String mediaId,
- String title, boolean isBrowseable, boolean isPlayable, long folderType,
- Bundle extras) {
+ private static MediaItem createFolder(
+ MediaDescriptionCompat.Builder descBuilder, String mediaId, String title,
+ boolean isBrowseable, boolean isPlayable, long folderType, Bundle extras) {
if (extras == null) extras = new Bundle();
extras.putLong(EXTRA_BCRADIO_FOLDER_TYPE, folderType);
- MediaDescription desc = descBuilder
+ MediaDescriptionCompat desc = descBuilder
.setMediaId(mediaId).setTitle(title).setExtras(extras).build();
int flags = 0;
@@ -273,7 +275,7 @@ public class BrowseTree {
if (mProgramListCache != null) return mProgramListCache;
mProgramListCache = new ArrayList<>();
- MediaDescription.Builder dbld = new MediaDescription.Builder();
+ MediaDescriptionCompat.Builder dbld = new MediaDescriptionCompat.Builder();
for (RadioManager.ProgramInfo program : mProgramListSnapshot) {
ProgramSelector sel = program.getSelector();
@@ -330,7 +332,7 @@ public class BrowseTree {
if (mFavoritesCache != null) return mFavoritesCache;
mFavoritesCache = new ArrayList<>();
- MediaDescription.Builder dbld = new MediaDescription.Builder();
+ MediaDescriptionCompat.Builder dbld = new MediaDescriptionCompat.Builder();
for (Program fav : mFavorites) {
ProgramSelector sel = fav.getSelector();
@@ -348,7 +350,7 @@ public class BrowseTree {
if (mRootChildren != null) return mRootChildren;
mRootChildren = new ArrayList<>();
- MediaDescription.Builder dbld = new MediaDescription.Builder();
+ MediaDescriptionCompat.Builder dbld = new MediaDescriptionCompat.Builder();
if (mProgramList != null) {
mRootChildren.add(createFolder(dbld, NODE_PROGRAMS,
mBrowserService.getString(R.string.program_list_text),
@@ -409,7 +411,7 @@ public class BrowseTree {
if (isEmpty()) return null;
Bundle extras = new Bundle();
extras.putString(EXTRA_BCRADIO_BAND_NAME_EN, mBandNameEn);
- return createFolder(new MediaDescription.Builder(), mMediaId,
+ return createFolder(new MediaDescriptionCompat.Builder(), mMediaId,
mBrowserService.getString(mBandName), true, true, BCRADIO_FOLDER_TYPE_BAND,
extras);
}
@@ -420,7 +422,7 @@ public class BrowseTree {
if (isEmpty()) return null;
mChannels = new ArrayList<>();
- MediaDescription.Builder dbld = new MediaDescription.Builder();
+ MediaDescriptionCompat.Builder dbld = new MediaDescriptionCompat.Builder();
for (BandDescriptor band : mBands) {
final int lowerLimit = band.getLowerLimit();
diff --git a/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ImageResolver.java b/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ImageResolver.java
index 5538a58..fd14045 100644
--- a/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ImageResolver.java
+++ b/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ImageResolver.java
@@ -16,9 +16,10 @@
package com.android.car.broadcastradio.support.platform;
-import android.annotation.Nullable;
import android.graphics.Bitmap;
+import androidx.annotation.Nullable;
+
/**
* Resolves metadata images.
*/
diff --git a/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ProgramInfoExt.java b/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ProgramInfoExt.java
index c96521a..a48dec2 100644
--- a/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ProgramInfoExt.java
+++ b/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ProgramInfoExt.java
@@ -16,18 +16,20 @@
package com.android.car.broadcastradio.support.platform;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.graphics.Bitmap;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioManager.ProgramInfo;
import android.hardware.radio.RadioMetadata;
-import android.media.MediaMetadata;
-import android.media.Rating;
+import android.support.v4.media.MediaMetadataCompat;
+import android.support.v4.media.RatingCompat;
+import android.support.v4.media.session.MediaSessionCompat;
import android.util.Log;
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Comparator;
@@ -50,9 +52,9 @@ public class ProgramInfoExt {
/**
* Flags to control how to fetch program name with {@link #getProgramName}.
*
- * Lower 16 bits are reserved for {@link ProgramSelectorExt#NameFlag}.
+ * Lower 16 bits are reserved for {@link ProgramSelectorExt.NameFlag}.
*/
- @IntDef(prefix = { "NAME_" }, flag = true, value = {
+ @IntDef(flag = true, value = {
ProgramSelectorExt.NAME_NO_MODULATION,
ProgramSelectorExt.NAME_MODULATION_ONLY,
NAME_NO_CHANNEL_FALLBACK,
@@ -128,7 +130,7 @@ public class ProgramInfoExt {
}
/**
- * Proposed reimplementation of {@link RadioManager#ProgramInfo#getMetadata}.
+ * Proposed reimplementation of {@link RadioManager.ProgramInfo#getMetadata}.
*
* As opposed to the original implementation, it never returns null.
*/
@@ -142,35 +144,35 @@ public class ProgramInfoExt {
}
/**
- * Converts {@link ProgramInfo} to {@link MediaMetadata} for displaying.
+ * Converts {@link ProgramInfo} to {@link MediaMetadataCompat} for displaying.
*
* <p>This method is meant to be used for displaying the currently playing station in
- * {@link MediaSession}, only a subset of keys populated in {@link ProgramInfo#toMediaMetadata}
+ * {@link MediaSessionCompat}, only a subset of keys populated in {@link #toMediaMetadata}
* will be populated in this method.
*
* <ul>
- * The following keys will be populated in the {@link MediaMetadata}:
- * <li>{@link MediaMetadata#METADATA_KEY_DISPLAY_TITLE}</li>
- * <li>{@link MediaMetadata#METADATA_KEY_DISPLAY_SUBTITLE}</li>
- * <li>{@link MediaMetadata#METADATA_KEY_ALBUM_ART}</li>
- * <li>{@link MediaMetadata#METADATA_KEY_USER_RATING}</li>
+ * The following keys will be populated in the {@link MediaMetadataCompat}:
+ * <li>{@link MediaMetadataCompat#METADATA_KEY_DISPLAY_TITLE}</li>
+ * <li>{@link MediaMetadataCompat#METADATA_KEY_DISPLAY_SUBTITLE}</li>
+ * <li>{@link MediaMetadataCompat#METADATA_KEY_ALBUM_ART}</li>
+ * <li>{@link MediaMetadataCompat#METADATA_KEY_USER_RATING}</li>
* <ul/>
*
* @param info {@link ProgramInfo} to convert
* @param isFavorite {@code true}, if a given program is a favorite
* @param imageResolver metadata images resolver/cache
* @param programNameOrder order of keys to look for program name in {@link ProgramInfo}
- * @return {@link MediaMetadata} object
+ * @return {@link MediaMetadataCompat} object
*/
@NonNull
- public static MediaMetadata toMediaDisplayMetadata(@NonNull ProgramInfo info,
+ public static MediaMetadataCompat toMediaDisplayMetadata(@NonNull ProgramInfo info,
boolean isFavorite, @NonNull ImageResolver imageResolver,
@NonNull String[] programNameOrder) {
Objects.requireNonNull(info, "info can not be null.");
Objects.requireNonNull(imageResolver, "imageResolver can not be null.");
Objects.requireNonNull(programNameOrder, "programNameOrder can not be null.");
- MediaMetadata.Builder bld = new MediaMetadata.Builder();
+ MediaMetadataCompat.Builder bld = new MediaMetadataCompat.Builder();
ProgramSelector selector;
ProgramSelector.Identifier logicallyTunedTo = info.getLogicallyTunedTo();
@@ -181,58 +183,60 @@ public class ProgramInfoExt {
selector = info.getSelector();
}
String displayTitle = ProgramSelectorExt.getDisplayName(selector, info.getChannel());
- bld.putString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE, displayTitle);
+ bld.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, displayTitle);
String subtitle = getProgramName(info, /* flags= */ 0, programNameOrder);
- bld.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE, subtitle);
+ bld.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, subtitle);
Bitmap bm = resolveAlbumArtBitmap(info.getMetadata(), imageResolver);
- if (bm != null) bld.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, bm);
+ if (bm != null) bld.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bm);
- bld.putRating(MediaMetadata.METADATA_KEY_USER_RATING, Rating.newHeartRating(isFavorite));
+ bld.putRating(MediaMetadataCompat.METADATA_KEY_USER_RATING,
+ RatingCompat.newHeartRating(isFavorite));
return bld.build();
}
/**
- * Converts {@link ProgramInfo} to {@link MediaMetadata}.
+ * Converts {@link ProgramInfo} to {@link MediaMetadataCompat}.
*
- * <p>This method is meant to be used for currently playing station in {@link MediaSession}.
+ * <p>This method is meant to be used for currently playing station in
+ * {@link MediaSessionCompat}.
*
* <ul>
- * The following keys will be populated in the {@link MediaMetadata}:
- * <li>{@link MediaMetadata#METADATA_KEY_DISPLAY_TITLE}</li>
- * <li>{@link MediaMetadata#METADATA_KEY_TITLE}</li>
- * <li>{@link MediaMetadata#METADATA_KEY_ARTIST}</li>
- * <li>{@link MediaMetadata#METADATA_KEY_ALBUM}</li>
- * <li>{@link MediaMetadata#METADATA_KEY_DISPLAY_SUBTITLE}</li>
- * <li>{@link MediaMetadata#METADATA_KEY_ALBUM_ART}</li>
- * <li>{@link MediaMetadata#METADATA_KEY_USER_RATING}</li>
+ * The following keys will be populated in the {@link MediaMetadataCompat}:
+ * <li>{@link MediaMetadataCompat#METADATA_KEY_DISPLAY_TITLE}</li>
+ * <li>{@link MediaMetadataCompat#METADATA_KEY_TITLE}</li>
+ * <li>{@link MediaMetadataCompat#METADATA_KEY_ARTIST}</li>
+ * <li>{@link MediaMetadataCompat#METADATA_KEY_ALBUM}</li>
+ * <li>{@link MediaMetadataCompat#METADATA_KEY_DISPLAY_SUBTITLE}</li>
+ * <li>{@link MediaMetadataCompat#METADATA_KEY_ALBUM_ART}</li>
+ * <li>{@link MediaMetadataCompat#METADATA_KEY_USER_RATING}</li>
* <ul/>
*
* @param info {@link ProgramInfo} to convert
* @param isFavorite {@code true}, if a given program is a favorite
* @param imageResolver metadata images resolver/cache
- * @return {@link MediaMetadata} object
+ * @return {@link MediaMetadataCompat} object
*/
- public static @NonNull MediaMetadata toMediaMetadata(@NonNull ProgramInfo info,
+ public static @NonNull MediaMetadataCompat toMediaMetadata(@NonNull ProgramInfo info,
boolean isFavorite, @Nullable ImageResolver imageResolver) {
- MediaMetadata.Builder bld = new MediaMetadata.Builder();
+ MediaMetadataCompat.Builder bld = new MediaMetadataCompat.Builder();
- bld.putString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE, getProgramName(info, 0));
+ bld.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, getProgramName(info, 0));
RadioMetadata meta = info.getMetadata();
if (meta != null) {
String title = meta.getString(RadioMetadata.METADATA_KEY_TITLE);
if (title != null) {
- bld.putString(MediaMetadata.METADATA_KEY_TITLE, title);
+ bld.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title);
}
String artist = meta.getString(RadioMetadata.METADATA_KEY_ARTIST);
if (artist != null) {
- bld.putString(MediaMetadata.METADATA_KEY_ARTIST, artist);
+ bld.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist);
}
String album = meta.getString(RadioMetadata.METADATA_KEY_ALBUM);
if (album != null) {
- bld.putString(MediaMetadata.METADATA_KEY_ALBUM, album);
+ bld.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, album);
}
if (title != null || artist != null) {
String subtitle;
@@ -243,14 +247,15 @@ public class ProgramInfoExt {
} else {
subtitle = title + TITLE_SEPARATOR + artist;
}
- bld.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE, subtitle);
+ bld.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, subtitle);
}
Bitmap bm = resolveAlbumArtBitmap(meta, imageResolver);
- if (bm != null) bld.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, bm);
+ if (bm != null) bld.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bm);
}
- bld.putRating(MediaMetadata.METADATA_KEY_USER_RATING, Rating.newHeartRating(isFavorite));
+ bld.putRating(MediaMetadataCompat.METADATA_KEY_USER_RATING,
+ RatingCompat.newHeartRating(isFavorite));
return bld.build();
}
diff --git a/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ProgramSelectorExt.java b/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ProgramSelectorExt.java
index 555176d..c0a4390 100644
--- a/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ProgramSelectorExt.java
+++ b/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/ProgramSelectorExt.java
@@ -16,15 +16,16 @@
package com.android.car.broadcastradio.support.platform;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.ProgramSelector.Identifier;
import android.hardware.radio.RadioManager;
import android.net.Uri;
import android.util.Log;
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.DecimalFormat;
@@ -73,9 +74,9 @@ public class ProgramSelectorExt {
/**
* Flags to control how channel values are converted to string with {@link #getDisplayName}.
*
- * Upper 16 bits are reserved for {@link ProgramInfoExt#NameFlag}.
+ * Upper 16 bits are reserved for {@link ProgramInfoExt.NameFlag}.
*/
- @IntDef(prefix = { "NAME_" }, flag = true, value = {
+ @IntDef(flag = true, value = {
NAME_NO_MODULATION,
NAME_MODULATION_ONLY,
})
@@ -113,7 +114,7 @@ public class ProgramSelectorExt {
}
// when pushed to the framework, remove similar code from HAL 2.0 service
- private static @ProgramSelector.ProgramType int identifierToProgramType(
+ private static int identifierToProgramType(
@NonNull Identifier primaryId) {
int idType = primaryId.getType();
switch (idType) {
@@ -230,8 +231,7 @@ public class ProgramSelectorExt {
* @param type identifier type to check for
* @return true, if sel contains any identifier of a given type
*/
- public static boolean hasId(@NonNull ProgramSelector sel,
- @ProgramSelector.IdentifierType int type) {
+ public static boolean hasId(@NonNull ProgramSelector sel, int type) {
try {
sel.getFirstId(type);
return true;
@@ -533,7 +533,7 @@ public class ProgramSelectorExt {
}
public long getStationId() {
- return mValue & 0xFFFFFFFF;
+ return mValue & 0xFFFFFFFFL;
}
public int getSubchannel() {
diff --git a/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/RadioMetadataExt.java b/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/RadioMetadataExt.java
index e7b6f3b..4192e83 100644
--- a/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/RadioMetadataExt.java
+++ b/car-broadcastradio-support/src/com/android/car/broadcastradio/support/platform/RadioMetadataExt.java
@@ -16,9 +16,13 @@
package com.android.car.broadcastradio.support.platform;
-import android.annotation.NonNull;
+import static android.hardware.radio.RadioMetadata.METADATA_KEY_ART;
+import static android.hardware.radio.RadioMetadata.METADATA_KEY_ICON;
+
import android.hardware.radio.RadioMetadata;
+import androidx.annotation.NonNull;
+
/**
* Proposed extensions to android.hardware.radio.RadioMetadata.
*
@@ -43,7 +47,7 @@ public class RadioMetadataExt {
* deprecation here and jump straight to the correct solution.
*/
public static long getGlobalBitmapId(@NonNull RadioMetadata meta, @NonNull String key) {
- int localId = meta.getBitmapId(key);
+ int localId = getBitmapId(meta, key);
if (localId == 0) return 0;
/* When generating global bitmap ID, we want them to remain stable between sessions
@@ -57,4 +61,9 @@ public class RadioMetadataExt {
*/
return ((long) sModuleId << 32) | localId;
}
+
+ private static int getBitmapId(@NonNull RadioMetadata meta, @NonNull String key) {
+ if (!METADATA_KEY_ICON.equals(key) && !METADATA_KEY_ART.equals(key)) return 0;
+ return meta.getInt(key);
+ }
}
diff --git a/car-broadcastradio-support/tests/Android.bp b/car-broadcastradio-support/tests/Android.bp
new file mode 100644
index 0000000..2cbca39
--- /dev/null
+++ b/car-broadcastradio-support/tests/Android.bp
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ default_team: "trendy_team_aaos_framework",
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+ name: "CarBroadcastRadioSupportTests",
+ platform_apis: true,
+ srcs: ["src/**/*.java"],
+ static_libs: [
+ "car-broadcastradio-support",
+ "androidx.test.rules",
+ "truth",
+ "mockito-target-extended",
+ ],
+ libs: ["android.test.base"],
+ test_suites: [
+ "general-tests",
+ "automotive-general-tests",
+ ],
+ // mockito-target-inline dependency
+ jni_libs: [
+ "libdexmakerjvmtiagent",
+ "libstaticjvmtiagent",
+ ],
+}
diff --git a/car-broadcastradio-support/tests/AndroidManifest.xml b/car-broadcastradio-support/tests/AndroidManifest.xml
new file mode 100644
index 0000000..458effa
--- /dev/null
+++ b/car-broadcastradio-support/tests/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.car.broadcastradio.tests">
+
+ <application android:debuggable="true">
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.car.broadcastradio.tests"
+ android:label="Tests for Car Broadcast Radio Support" >
+ </instrumentation>
+</manifest> \ No newline at end of file
diff --git a/car-broadcastradio-support/tests/src/com/android/car/broadcastradio/support/platform/ProgramInfoExtTest.java b/car-broadcastradio-support/tests/src/com/android/car/broadcastradio/support/platform/ProgramInfoExtTest.java
new file mode 100644
index 0000000..37e74dc
--- /dev/null
+++ b/car-broadcastradio-support/tests/src/com/android/car/broadcastradio/support/platform/ProgramInfoExtTest.java
@@ -0,0 +1,203 @@
+/**
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.broadcastradio.support.platform;
+
+import static org.mockito.Mockito.when;
+
+import android.graphics.Bitmap;
+import android.hardware.radio.ProgramSelector;
+import android.hardware.radio.RadioManager;
+import android.hardware.radio.RadioMetadata;
+import android.support.v4.media.MediaMetadataCompat;
+
+import com.google.common.truth.Expect;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.util.Comparator;
+
+@RunWith(MockitoJUnitRunner.class)
+public final class ProgramInfoExtTest {
+
+ private static final long FM_FREQUENCY = 88_500;
+ private static final String RDS_VALUE = "TestRds";
+ private static final String PROGRAM_NAME_VALUE = "TestProgramName";
+ private static final String TITLE_VALUE = "TestTitle";
+ private static final String ARTIST_VALUE = "TestArtist";
+ private static final String ALBUM_VALUE = "TestAlbum";
+ private static final int ART_VALUE = 1;
+ private static final ProgramSelector.Identifier FM_IDENTIFIER = new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, FM_FREQUENCY);
+ private static final ProgramSelector FM_SELECTOR = new ProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_FM, FM_IDENTIFIER, /* secondaryIds= */ null,
+ /* vendorIds= */ null);
+ private static final ProgramSelector.Identifier DAB_DMB_SID_EXT_IDENTIFIER =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
+ 0xA000000111L);
+ private static final ProgramSelector.Identifier DAB_ENSEMBLE_IDENTIFIER =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
+ /* value= */ 0x1001);
+ private static final ProgramSelector.Identifier DAB_FREQUENCY_IDENTIFIER =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
+ /* value= */ 220_352);
+ private static final ProgramSelector DAB_SELECTOR = new ProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_DAB, DAB_DMB_SID_EXT_IDENTIFIER,
+ new ProgramSelector.Identifier[]{DAB_FREQUENCY_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER},
+ /* vendorIds= */ null);
+ private static final RadioMetadata RADIO_METADATA = new RadioMetadata.Builder()
+ .putString(RadioMetadata.METADATA_KEY_RDS_PS, RDS_VALUE)
+ .putString(RadioMetadata.METADATA_KEY_PROGRAM_NAME, PROGRAM_NAME_VALUE)
+ .putString(RadioMetadata.METADATA_KEY_TITLE, TITLE_VALUE)
+ .putString(RadioMetadata.METADATA_KEY_ARTIST, ARTIST_VALUE)
+ .putString(RadioMetadata.METADATA_KEY_ALBUM, ALBUM_VALUE)
+ .putInt(RadioMetadata.METADATA_KEY_ART, ART_VALUE).build();
+ private static final RadioMetadata EMPTY_RADIO_METADATA = new RadioMetadata.Builder().build();
+ private static final RadioManager.ProgramInfo FM_INFO = new RadioManager.ProgramInfo(
+ FM_SELECTOR, FM_IDENTIFIER, FM_IDENTIFIER, /* relatedContents= */ null,
+ /* infoFlags= */ 0, /* signalQuality= */ 1, RADIO_METADATA,
+ /* vendorInfo= */ null);
+ private static final RadioManager.ProgramInfo FM_INFO_WITH_EMPTY_METADATA =
+ new RadioManager.ProgramInfo(FM_SELECTOR, FM_IDENTIFIER, FM_IDENTIFIER,
+ /* relatedContents= */ null, /* infoFlags= */ 0, /* signalQuality= */ 1,
+ EMPTY_RADIO_METADATA, /* vendorInfo= */ null);
+ private static final RadioManager.ProgramInfo DAB_INFO_WITH_EMPTY_METADATA =
+ new RadioManager.ProgramInfo(DAB_SELECTOR, DAB_DMB_SID_EXT_IDENTIFIER,
+ DAB_FREQUENCY_IDENTIFIER, /* relatedContents= */ null, /* infoFlags= */ 0,
+ /* signalQuality= */ 1, EMPTY_RADIO_METADATA, /* vendorInfo= */ null);
+
+ private static final Comparator<ProgramSelector> SELECTOR_COMPARATOR =
+ new ProgramSelectorExt.ProgramSelectorComparator();
+ private static final Comparator<RadioManager.ProgramInfo> PROGRAM_INFO_COMPARATOR =
+ new ProgramInfoExt.ProgramInfoComparator();
+
+ @Rule
+ public final Expect mExpect = Expect.create();
+
+ @Test
+ public void getProgramName() {
+ mExpect.withMessage("Program name")
+ .that(ProgramInfoExt.getProgramName(FM_INFO, /* flags= */ 0))
+ .isEqualTo(PROGRAM_NAME_VALUE);
+ }
+
+ @Test
+ public void getProgramName_withProgramNameOrder() {
+ String[] programNameOrder = new String[] {RadioMetadata.METADATA_KEY_RDS_PS,
+ RadioMetadata.METADATA_KEY_PROGRAM_NAME};
+
+ mExpect.withMessage("Program name with self-defined program name order")
+ .that(ProgramInfoExt.getProgramName(FM_INFO, /* flags= */ 0, programNameOrder))
+ .isEqualTo(RDS_VALUE);
+ }
+
+ @Test
+ public void getProgramName_forFmSelectorWithoutProgramNameMetadata() {
+ String expectedName = ProgramSelectorExt.formatAmFmFrequency(
+ FM_INFO_WITH_EMPTY_METADATA.getPhysicallyTunedTo().getValue(), /* flags= */ 0);
+
+ mExpect.withMessage("FM Program name without program name metadata")
+ .that(ProgramInfoExt.getProgramName(FM_INFO_WITH_EMPTY_METADATA, /* flags= */ 0))
+ .isEqualTo(expectedName);
+ }
+
+ @Test
+ public void getProgramName_forDabProgramWithoutProgramNameMetadata() {
+ String expectedName = ProgramSelectorExt.getDisplayName(
+ DAB_INFO_WITH_EMPTY_METADATA.getSelector(), /* flags= */ 0);
+
+ mExpect.withMessage("DAB Program name without program name metadata")
+ .that(ProgramInfoExt.getProgramName(DAB_INFO_WITH_EMPTY_METADATA, /* flags= */ 0))
+ .isEqualTo(expectedName);
+ }
+
+ @Test
+ public void getMetadata() {
+ mExpect.withMessage("FM radio metadata")
+ .that(ProgramInfoExt.getMetadata(FM_INFO)).isEqualTo(RADIO_METADATA);
+ }
+
+ @Test
+ public void getMetadata_withNullMetadata() {
+ RadioManager.ProgramInfo infoWithNullMetadata = new RadioManager.ProgramInfo(
+ FM_SELECTOR, FM_IDENTIFIER, FM_IDENTIFIER, /* relatedContents= */ null,
+ /* infoFlags= */ 0, /* signalQuality= */ 1, /* metadata= */ null,
+ /* vendorInfo= */ null);
+
+ mExpect.withMessage("FM radio metadata with null metadata")
+ .that(ProgramInfoExt.getMetadata(infoWithNullMetadata))
+ .isEqualTo(EMPTY_RADIO_METADATA);
+ }
+
+ @Test
+ public void toMediaDisplayMetadata() {
+ String[] programNameOrder = new String[] {RadioMetadata.METADATA_KEY_RDS_PS,
+ RadioMetadata.METADATA_KEY_PROGRAM_NAME};
+ Bitmap bitmapMock = Mockito.mock(Bitmap.class);
+ ImageResolver imageResolver = Mockito.mock(ImageResolver.class);
+ when(imageResolver.resolve(ART_VALUE)).thenReturn(bitmapMock);
+
+ MediaMetadataCompat mediaDisplayMetadata = ProgramInfoExt.toMediaDisplayMetadata(FM_INFO,
+ /* isFavorite= */ true, imageResolver, programNameOrder);
+
+ mExpect.withMessage("Media display title in media display metadata")
+ .that(mediaDisplayMetadata.getString(
+ MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE))
+ .isEqualTo(ProgramSelectorExt.getDisplayName(FM_INFO.getSelector(),
+ FM_INFO.getChannel()));
+ mExpect.withMessage("Media display subtitle in media display metadata")
+ .that(mediaDisplayMetadata.getString(
+ MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE))
+ .isEqualTo(ProgramInfoExt.getProgramName(FM_INFO, /* flags= */ 0,
+ programNameOrder));
+ mExpect.withMessage("Album art in media display metadata")
+ .that(mediaDisplayMetadata.getBitmap(
+ MediaMetadataCompat.METADATA_KEY_ALBUM_ART)).isEqualTo(bitmapMock);
+ }
+
+ @Test
+ public void toMediaMetadata() {
+ MediaMetadataCompat mediaMetadata = ProgramInfoExt.toMediaMetadata(FM_INFO,
+ /* isFavorite= */ true, /* imageResolver= */ null);
+
+ mExpect.withMessage("Media display title").that(mediaMetadata
+ .getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE))
+ .isEqualTo(ProgramInfoExt.getProgramName(FM_INFO, /* flags= */ 0));
+ mExpect.withMessage("Media title").that(mediaMetadata.getString(
+ MediaMetadataCompat.METADATA_KEY_TITLE)).isEqualTo(TITLE_VALUE);
+ mExpect.withMessage("Media artist").that(mediaMetadata.getString(
+ MediaMetadataCompat.METADATA_KEY_ARTIST)).isEqualTo(ARTIST_VALUE);
+ mExpect.withMessage("Media album").that(mediaMetadata.getString(
+ MediaMetadataCompat.METADATA_KEY_ALBUM)).isEqualTo(ALBUM_VALUE);
+ }
+
+ @Test
+ public void compare_withSelectorsOfDifferentTypes() {
+ ProgramSelector fmSel2 = ProgramSelectorExt.createAmFmSelector(FM_FREQUENCY + 200);
+ RadioManager.ProgramInfo fmInfo2 = new RadioManager.ProgramInfo(fmSel2,
+ fmSel2.getPrimaryId(), fmSel2.getPrimaryId(), /* relatedContents= */ null,
+ /* infoFlags= */ 1, /* signalQuality= */ 0, new RadioMetadata.Builder().build(),
+ /* vendorInfo= */ null);
+ int expectedResult = SELECTOR_COMPARATOR.compare(fmSel2, FM_SELECTOR);
+
+ mExpect.withMessage("Comparison between FM stations")
+ .that(PROGRAM_INFO_COMPARATOR.compare(fmInfo2, FM_INFO)).isEqualTo(expectedResult);
+ }
+}
diff --git a/car-broadcastradio-support/tests/src/com/android/car/broadcastradio/support/platform/ProgramSelectorExtTest.java b/car-broadcastradio-support/tests/src/com/android/car/broadcastradio/support/platform/ProgramSelectorExtTest.java
new file mode 100644
index 0000000..659ecfc
--- /dev/null
+++ b/car-broadcastradio-support/tests/src/com/android/car/broadcastradio/support/platform/ProgramSelectorExtTest.java
@@ -0,0 +1,356 @@
+/**
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.broadcastradio.support.platform;
+
+import static org.junit.Assert.assertThrows;
+
+import android.hardware.radio.ProgramSelector;
+
+import com.google.common.truth.Expect;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.Comparator;
+
+public final class ProgramSelectorExtTest {
+
+ private static final long AM_FREQUENCY_VALUE = 700;
+ private static final long FM_FREQUENCY_VALUE = 88_500;
+ private static final long HD_FREQUENCY_VALUE = 97_100;
+ private static final int HD_SUBCHANNEL_VALUE = 1;
+ private static final int HD_STATION_ID_VALUE = 0x01;
+ private static final long DAB_FREQUENCY_VALUE = 220_352;
+ private static final long DAB_ENSEMBLE_VALUE = 0x1001;
+ private static final long DAB_SID_VALUE = 0x112;
+ private static final int DAB_ECC_VALUE = 0xA0;
+ private static final int DAB_SCIDS_VALUE = 1;
+ private static final ProgramSelector.Identifier FM_IDENTIFIER = new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, FM_FREQUENCY_VALUE);
+ private static final ProgramSelector.Identifier HD_STATION_EXT_IDENTIFIER =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_HD_STATION_ID_EXT,
+ (HD_FREQUENCY_VALUE << 36) | ((long) HD_SUBCHANNEL_VALUE << 32)
+ | HD_STATION_ID_VALUE);
+ private static final ProgramSelector.Identifier DAB_DMB_SID_EXT_IDENTIFIER =
+ createDabSidExtId(DAB_SID_VALUE, DAB_ECC_VALUE, DAB_SCIDS_VALUE);
+ private static final ProgramSelector.Identifier DAB_ENSEMBLE_IDENTIFIER =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
+ DAB_ENSEMBLE_VALUE);
+ private static final ProgramSelector.Identifier DAB_FREQUENCY_IDENTIFIER =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
+ DAB_FREQUENCY_VALUE);
+ private static final ProgramSelector FM_SELECTOR = new ProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_FM, FM_IDENTIFIER, /* secondaryIds= */ null,
+ /* vendorIds= */ null);
+ private static final ProgramSelector HD_SELECTOR = new ProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_FM_HD, HD_STATION_EXT_IDENTIFIER,
+ new ProgramSelector.Identifier[]{}, /* vendorIds= */ null);
+ private static final ProgramSelector DAB_SELECTOR = new ProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_DAB, DAB_DMB_SID_EXT_IDENTIFIER,
+ new ProgramSelector.Identifier[]{DAB_FREQUENCY_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER},
+ /* vendorIds= */ null);
+ private static final Comparator<ProgramSelector> SELECTOR_COMPARATOR =
+ new ProgramSelectorExt.ProgramSelectorComparator();
+
+ @Rule
+ public final Expect mExpect = Expect.create();
+
+ @Test
+ public void isAmFrequency_withAmFrequency() {
+ mExpect.withMessage("AM frequency")
+ .that(ProgramSelectorExt.isAmFrequency(AM_FREQUENCY_VALUE)).isTrue();
+ }
+
+ @Test
+ public void isAmFrequency_withFmFrequency() {
+ mExpect.withMessage("Non-AM frequency")
+ .that(ProgramSelectorExt.isAmFrequency(FM_FREQUENCY_VALUE)).isFalse();
+ }
+
+ @Test
+ public void isFmFrequency_withAmFrequency() {
+ mExpect.withMessage("Non-FM frequency")
+ .that(ProgramSelectorExt.isFmFrequency(AM_FREQUENCY_VALUE)).isFalse();
+ }
+
+ @Test
+ public void isFmFrequency_withFmFrequency() {
+ mExpect.withMessage("FM frequency")
+ .that(ProgramSelectorExt.isFmFrequency(FM_FREQUENCY_VALUE)).isTrue();
+ }
+
+ @Test
+ public void createAmFmSelector() {
+ mExpect.withMessage("FM selector").that(ProgramSelectorExt.createAmFmSelector(
+ FM_FREQUENCY_VALUE)).isEqualTo(FM_SELECTOR);
+ }
+
+ @Test
+ public void createAmFmSelector_withInvalidFrequency_throwsException() {
+ long invalidFrequency = -1;
+
+ IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> {
+ ProgramSelectorExt.createAmFmSelector(invalidFrequency);
+ });
+
+ mExpect.withMessage("Invalid frequency exception").that(thrown).hasMessageThat()
+ .contains("illegal frequency value");
+ }
+
+ @Test
+ public void hasId_forSelectorWithIdAsPrimaryId() {
+ mExpect.withMessage("AM/FM id in selector").that(ProgramSelectorExt.hasId(FM_SELECTOR,
+ ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY)).isTrue();
+ }
+
+ @Test
+ public void hasId_forSelectorWithIdInSecondaryIds() {
+ mExpect.withMessage("DAB ensemble id in selector").that(ProgramSelectorExt.hasId(
+ DAB_SELECTOR, ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY)).isTrue();
+ }
+
+ @Test
+ public void hasId_forSelectorWithoutId() {
+ mExpect.withMessage("Id type beyond selector ids").that(ProgramSelectorExt.hasId(
+ HD_SELECTOR, ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY)).isFalse();
+ }
+
+ @Test
+ public void isAmFmProgram_withAmFmSelector() {
+ mExpect.withMessage("FM selector of AM/FM type program")
+ .that(ProgramSelectorExt.isAmFmProgram(FM_SELECTOR)).isTrue();
+ }
+
+ @Test
+ public void isAmFmProgram_withHdSelector() {
+ mExpect.withMessage("HD selector of AM/FM type program")
+ .that(ProgramSelectorExt.isAmFmProgram(HD_SELECTOR)).isTrue();
+ }
+
+ @Test
+ public void isAmFmProgram_withDabSelector() {
+ mExpect.withMessage("DAB selector of non-AM/FM type program")
+ .that(ProgramSelectorExt.isAmFmProgram(DAB_SELECTOR)).isFalse();
+ }
+
+ @Test
+ public void getFrequency_withAmFmSelector() {
+ mExpect.withMessage("Frequency of FM selector")
+ .that(ProgramSelectorExt.getFrequency(FM_SELECTOR)).isEqualTo(FM_FREQUENCY_VALUE);
+ }
+
+ @Test
+ public void getFrequency_withHdSelector() {
+ mExpect.withMessage("Frequency of HD selector")
+ .that(ProgramSelectorExt.getFrequency(HD_SELECTOR)).isEqualTo(HD_FREQUENCY_VALUE);
+ }
+
+ @Test
+ public void getFrequency_withDabSelector() {
+ mExpect.withMessage("Frequency of DAB selector")
+ .that(ProgramSelectorExt.getFrequency(DAB_SELECTOR)).isEqualTo(DAB_FREQUENCY_VALUE);
+ }
+
+ @Test
+ public void getFrequency_withSelectorWithoutFrequency() {
+ ProgramSelector dabSelectorWithoutFrequency = new ProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_DAB, DAB_DMB_SID_EXT_IDENTIFIER,
+ new ProgramSelector.Identifier[]{DAB_ENSEMBLE_IDENTIFIER}, /* vendorIds= */ null);
+
+ mExpect.withMessage("Frequency of a selector without frequency")
+ .that(ProgramSelectorExt.getFrequency(dabSelectorWithoutFrequency))
+ .isEqualTo(ProgramSelectorExt.INVALID_IDENTIFIER_VALUE);
+ }
+
+ @Test
+ public void getDabEnsemble_withDabSelector() {
+ mExpect.withMessage("Ensemble of DAB selector").that(
+ ProgramSelectorExt.getDabEnsemble(DAB_SELECTOR)).isEqualTo(DAB_ENSEMBLE_VALUE);
+ }
+
+ @Test
+ public void getDabEnsemble_withNonDabSelector() {
+ mExpect.withMessage("Ensemble of FM selector")
+ .that(ProgramSelectorExt.getDabEnsemble(FM_SELECTOR))
+ .isEqualTo(ProgramSelectorExt.INVALID_IDENTIFIER_VALUE);
+ }
+
+ @Test
+ public void asHdPrimary_withNonHdId() {
+ mExpect.withMessage("HD Primary identifier extension for FM id")
+ .that(ProgramSelectorExt.IdentifierExt.asHdPrimary(FM_IDENTIFIER)).isNull();
+ }
+
+ @Test
+ public void getStationId_forHdPrimary() {
+ mExpect.withMessage("Station id of HD primary identifier extension")
+ .that(ProgramSelectorExt.IdentifierExt.asHdPrimary(HD_STATION_EXT_IDENTIFIER)
+ .getStationId()).isEqualTo(HD_STATION_ID_VALUE);
+ }
+
+ @Test
+ public void getSubchannel_forHdPrimary() {
+ mExpect.withMessage("Sub-channel of HD primary identifier extension")
+ .that(ProgramSelectorExt.IdentifierExt.asHdPrimary(HD_STATION_EXT_IDENTIFIER)
+ .getSubchannel()).isEqualTo(HD_SUBCHANNEL_VALUE);
+ }
+
+ @Test
+ public void getFrequency_forHdPrimary() {
+ mExpect.withMessage("Frequency of HD primary identifier extension")
+ .that(ProgramSelectorExt.IdentifierExt.asHdPrimary(HD_STATION_EXT_IDENTIFIER)
+ .getFrequency()).isEqualTo(HD_FREQUENCY_VALUE);
+ }
+
+ @Test
+ public void asDabPrimary_withNonDabId() {
+ mExpect.withMessage("DAB Primary identifier extension for FM id")
+ .that(ProgramSelectorExt.IdentifierExt.asDabPrimary(FM_IDENTIFIER)).isNull();
+ }
+ @Test
+ public void getSId_forDabPrimary() {
+ mExpect.withMessage("Station Id of DAB primary identifier extension")
+ .that(ProgramSelectorExt.IdentifierExt.asDabPrimary(DAB_DMB_SID_EXT_IDENTIFIER)
+ .getSId()).isEqualTo(DAB_SID_VALUE);
+ }
+
+ @Test
+ public void getEcc_forDabPrimary() {
+ mExpect.withMessage("ECC of DAB primary identifier extension")
+ .that(ProgramSelectorExt.IdentifierExt.asDabPrimary(DAB_DMB_SID_EXT_IDENTIFIER)
+ .getEcc()).isEqualTo(DAB_ECC_VALUE);
+ }
+
+ @Test
+ public void getSCIdS_forDabPrimary() {
+ mExpect.withMessage("SCIdS of DAB primary identifier extension")
+ .that(ProgramSelectorExt.IdentifierExt.asDabPrimary(DAB_DMB_SID_EXT_IDENTIFIER)
+ .getSCIdS()).isEqualTo(DAB_SCIDS_VALUE);
+ }
+
+ @Test
+ public void compare_withTwoFmSelectorsForProgramSelectorComparator() {
+ ProgramSelector fmSel2 = ProgramSelectorExt.createAmFmSelector(FM_FREQUENCY_VALUE + 200);
+
+ mExpect.withMessage("Comparison between two FM selectors")
+ .that(SELECTOR_COMPARATOR.compare(FM_SELECTOR, fmSel2)).isEqualTo(-1);
+ }
+
+ @Test
+ public void compare_withFmAndHdSelectors() {
+ mExpect.withMessage("Comparison between FM and HD selectors")
+ .that(SELECTOR_COMPARATOR.compare(FM_SELECTOR, HD_SELECTOR)).isEqualTo(-1);
+ }
+
+ @Test
+ public void compare_withHdSelectorsWithDifferentFrequncies() {
+ ProgramSelector.Identifier hdId = new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_HD_STATION_ID_EXT,
+ ((HD_FREQUENCY_VALUE + 200) << 36) | HD_STATION_ID_VALUE);
+ ProgramSelector hdSel = new ProgramSelector(ProgramSelector.PROGRAM_TYPE_FM_HD, hdId,
+ new ProgramSelector.Identifier[]{}, /* vendorIds= */ null);
+
+ mExpect.withMessage("Comparison between HD selectors with different frequencies")
+ .that(SELECTOR_COMPARATOR.compare(hdSel, HD_SELECTOR)).isEqualTo(1);
+ }
+
+ @Test
+ public void compare_withHdSelectorsWithDifferentSubchannels() {
+ ProgramSelector.Identifier hdId2 = new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_HD_STATION_ID_EXT,
+ (HD_FREQUENCY_VALUE << 36) | HD_STATION_ID_VALUE);
+ ProgramSelector hdSel2 = new ProgramSelector(ProgramSelector.PROGRAM_TYPE_FM_HD, hdId2,
+ new ProgramSelector.Identifier[]{}, /* vendorIds= */ null);
+
+ mExpect.withMessage("Comparison between HD selectors with different subchannels")
+ .that(SELECTOR_COMPARATOR.compare(hdSel2, HD_SELECTOR)).isEqualTo(-1);
+ }
+
+ @Test
+ public void compare_withDabSelectorsWithDifferentFrequencies() {
+ ProgramSelector.Identifier dabFrequencyId2 = new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY, 174_928);
+ ProgramSelector.Identifier dabEnsembleId2 = new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE, DAB_ENSEMBLE_VALUE + 1);
+ ProgramSelector dabSel2 = new ProgramSelector(ProgramSelector.PROGRAM_TYPE_DAB,
+ DAB_DMB_SID_EXT_IDENTIFIER,
+ new ProgramSelector.Identifier[]{dabFrequencyId2, dabEnsembleId2},
+ /* vendorIds= */ null);
+
+ mExpect.withMessage("Comparison between DAB selectors with different frequencies")
+ .that(SELECTOR_COMPARATOR.compare(dabSel2, DAB_SELECTOR)).isEqualTo(-1);
+ }
+
+ @Test
+ public void compare_withDabSelectorsWithDifferentEccs() {
+ ProgramSelector.Identifier dabExtId2 = createDabSidExtId(DAB_SID_VALUE - 1,
+ DAB_ECC_VALUE + 1, DAB_SCIDS_VALUE + 1);
+ ProgramSelector dabSel2 = new ProgramSelector(ProgramSelector.PROGRAM_TYPE_DAB,
+ dabExtId2, new ProgramSelector.Identifier[]{DAB_FREQUENCY_IDENTIFIER,
+ DAB_ENSEMBLE_IDENTIFIER}, /* vendorIds= */ null);
+
+ mExpect.withMessage("Comparison between DAB selectors with different ECC values")
+ .that(SELECTOR_COMPARATOR.compare(dabSel2, DAB_SELECTOR)).isEqualTo(1);
+ }
+
+ @Test
+ public void compare_withDabSelectorsWithDifferentSIds() {
+ ProgramSelector.Identifier dabExtId2 = createDabSidExtId(DAB_SID_VALUE - 1,
+ DAB_ECC_VALUE, DAB_SCIDS_VALUE + 1);
+ ProgramSelector dabSel2 = new ProgramSelector(ProgramSelector.PROGRAM_TYPE_DAB,
+ dabExtId2, new ProgramSelector.Identifier[]{DAB_FREQUENCY_IDENTIFIER,
+ DAB_ENSEMBLE_IDENTIFIER}, /* vendorIds= */ null);
+
+ mExpect.withMessage("Comparison between DAB selectors with different SId values")
+ .that(SELECTOR_COMPARATOR.compare(dabSel2, DAB_SELECTOR)).isEqualTo(-1);
+ }
+
+ @Test
+ public void compare_withDabSelectorsWithDifferentSCIds() {
+ ProgramSelector.Identifier dabExtId2 = createDabSidExtId(DAB_SID_VALUE,
+ DAB_ECC_VALUE, DAB_SCIDS_VALUE + 1);
+ ProgramSelector dabSel2 = new ProgramSelector(ProgramSelector.PROGRAM_TYPE_DAB,
+ dabExtId2, new ProgramSelector.Identifier[]{DAB_FREQUENCY_IDENTIFIER,
+ DAB_ENSEMBLE_IDENTIFIER}, /* vendorIds= */ null);
+
+ mExpect.withMessage("Comparison between DAB selectors with different SCId values")
+ .that(SELECTOR_COMPARATOR.compare(dabSel2, DAB_SELECTOR)).isEqualTo(1);
+ }
+
+ @Test
+ public void compare_withDabSelectorsWithDifferentEnsembles() {
+ ProgramSelector.Identifier dabEnsembleId2 = new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE, DAB_ENSEMBLE_VALUE + 1);
+ ProgramSelector dabSel2 = new ProgramSelector(ProgramSelector.PROGRAM_TYPE_DAB,
+ DAB_DMB_SID_EXT_IDENTIFIER, new ProgramSelector.Identifier[]{
+ DAB_FREQUENCY_IDENTIFIER, dabEnsembleId2}, /* vendorIds= */ null);
+
+ mExpect.withMessage("Comparison between DAB selectors with different ensembles")
+ .that(SELECTOR_COMPARATOR.compare(dabSel2, DAB_SELECTOR)).isEqualTo(1);
+ }
+
+ @Test
+ public void compare_withSelectorsOfDifferentTypes() {
+ mExpect.withMessage("Comparison between HD and DAB selectors with different types")
+ .that(SELECTOR_COMPARATOR.compare(HD_SELECTOR, DAB_SELECTOR)).isEqualTo(-1);
+ }
+
+ private static ProgramSelector.Identifier createDabSidExtId(long sid, int ecc, int sCIdS) {
+ return new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
+ ((long) sCIdS << 40) | ((long) ecc << 32) | sid);
+ }
+}