diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-06-23 07:17:36 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-06-23 07:17:36 +0000 |
commit | 07e4079f22e32e03157ab8fa08b3344144f1525d (patch) | |
tree | 25ba830abd5976a81a779d2e21d57209779aa0d5 | |
parent | 9d77fd5190ed925046298442a288504672e3c1de (diff) | |
parent | 9c51019a4cc09214d4d2e72fdce092fca53a8831 (diff) | |
download | systemlibs-07e4079f22e32e03157ab8fa08b3344144f1525d.tar.gz |
Snap for 11992377 from 9c51019a4cc09214d4d2e72fdce092fca53a8831 to busytown-mac-infra-releasebusytown-mac-infra-release
Change-Id: Ifb442a26a5259cbd51ede5aff97696de99d92bfb
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); + } +} |