diff --git a/dataprovider-retrofit/build.gradle.kts b/dataprovider-retrofit/build.gradle.kts
index f9c1aa4..5b9137b 100644
--- a/dataprovider-retrofit/build.gradle.kts
+++ b/dataprovider-retrofit/build.gradle.kts
@@ -53,7 +53,6 @@ android {
dependencies {
api(project(":data"))
api(libs.retrofit)
- compileOnly(libs.androidx.annotation)
api(platform(libs.retrofit.bom))
implementation(libs.retrofit.converter.kotlinx.serialization)
implementation(libs.okhttp.logging.interceptor)
diff --git a/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/request/IlHost.java b/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/request/IlHost.java
deleted file mode 100644
index eb62c0f..0000000
--- a/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/request/IlHost.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package ch.srg.dataProvider.integrationlayer.request;
-
-import android.net.Uri;
-
-import androidx.annotation.NonNull;
-
-import java.io.Serializable;
-
-/**
- * Copyright (c) SRG SSR. All rights reserved.
- *
- * License information is available from the LICENSE file.
- */
-public final class IlHost implements Serializable {
- public static final IlHost PROD = new IlHost("PROD", "il.srgssr.ch");
- public static final IlHost TEST = new IlHost("TEST", "il-test.srgssr.ch");
- public static final IlHost STAGE = new IlHost("STAGE", "il-stage.srgssr.ch");
- public static final IlHost MMF = new IlHost("MMF", "play-mmf.herokuapp.com/android_26CE9E49-9600");
- public static final IlHost MMF_PUBLIC = new IlHost("MMF", "play-mmf.herokuapp.com");
- public static final IlHost PROD_SAM = new IlHost("PROD_SAM", "il.srgssr.ch/sam");
- public static final IlHost TEST_SAM = new IlHost("TEST_SAM", "il-test.srgssr.ch/sam");
- public static final IlHost STAGE_SAM = new IlHost("STAGE_SAM", "il-stage.srgssr.ch/sam");
-
- @NonNull
- private final String value;
- @NonNull
- private final String name;
-
- /**
- * @param name designed name
- * @param value hostname of the integration layer url
- */
- public IlHost(@NonNull final String name, @NonNull final String value) {
- this.name = name;
- this.value = value;
- }
-
- @NonNull
- public String getValue() {
- return value;
- }
-
- @NonNull
- public String getName() {
- return name;
- }
-
- @NonNull
- public Uri getHostUri() {
- return Uri.parse("https://" + value);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- IlHost ilHost = (IlHost) o;
-
- if (!value.equals(ilHost.value)) return false;
- return name.equals(ilHost.name);
- }
-
- @Override
- public int hashCode() {
- int result = value.hashCode();
- result = 31 * result + name.hashCode();
- return result;
- }
-
- @NonNull
- @Override
- public String toString() {
- return name;
- }
-}
diff --git a/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/request/IlHost.kt b/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/request/IlHost.kt
new file mode 100644
index 0000000..d9f1e69
--- /dev/null
+++ b/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/request/IlHost.kt
@@ -0,0 +1,52 @@
+package ch.srg.dataProvider.integrationlayer.request
+
+import android.net.Uri
+import java.io.Serializable
+
+/**
+ * Copyright (c) SRG SSR. All rights reserved.
+ *
+ * License information is available from the LICENSE file.
+ *
+ * @property name designed name
+ * @property value hostname of the integration layer url
+ */
+data class IlHost(
+ val name: String,
+ val value: String,
+) : Serializable {
+ val hostUri: Uri
+ get() = Uri.parse("https://$value")
+
+ override fun toString(): String {
+ return name
+ }
+
+ companion object {
+ private const val serialVersionUID = 1L
+
+ @JvmField
+ val PROD = IlHost("PROD", "il.srgssr.ch")
+
+ @JvmField
+ val TEST = IlHost("TEST", "il-test.srgssr.ch")
+
+ @JvmField
+ val STAGE = IlHost("STAGE", "il-stage.srgssr.ch")
+
+ @JvmField
+ val MMF = IlHost("MMF", "play-mmf.herokuapp.com/android_26CE9E49-9600")
+
+ @JvmField
+ val MMF_PUBLIC = IlHost("MMF", "play-mmf.herokuapp.com")
+
+ @JvmField
+ val PROD_SAM = IlHost("PROD_SAM", "il.srgssr.ch/sam")
+
+ @JvmField
+ val TEST_SAM = IlHost("TEST_SAM", "il-test.srgssr.ch/sam")
+
+ @JvmField
+ val STAGE_SAM = IlHost("STAGE_SAM", "il-stage.srgssr.ch/sam")
+ }
+}
diff --git a/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/utils/IlUrn.java b/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/utils/IlUrn.java
deleted file mode 100755
index e5393d4..0000000
--- a/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/utils/IlUrn.java
+++ /dev/null
@@ -1,186 +0,0 @@
-package ch.srg.dataProvider.integrationlayer.utils;
-
-import android.text.TextUtils;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * This very simple class represents a URN provided by the IL.
- */
-public class IlUrn {
- private final static Pattern PATTERN_BUMAM = Pattern.compile("^urn:(srf|rts|rsi|rtr|swi|default):(?:[^:]+:)?(video|audio|videoset|show|assetgroup):([^:]+)$", Pattern.CASE_INSENSITIVE);
- private final static Pattern PATTERN_SWISSTXT = Pattern.compile("^urn:(swisstxt):(?:[^:]+:)?(video|audio|videoset|show|assetgroup):(srf|rts|rsi|rtr|swi):([^:]+)$", Pattern.CASE_INSENSITIVE);
-
- public static final String ASSET_VIDEO = "video";
- public static final String ASSET_VIDEO_SET = "videoset";
- public static final String ASSET_AUDIO = "audio";
- public static final String ASSET_SHOW = "show";
- public static final String ASSET_GROUP = "assetgroup";
-
- private String underlying;
-
- private String bu;
- private String assetType;
- private String id;
-
- /**
- * @param urn urn can be any media identifier, valid or not
- * @throws IllegalArgumentException if not a valid urn
- */
- public IlUrn(@NonNull String urn) throws IllegalArgumentException {
- if (!parseBuMam(urn)
- && !parseSwissTxt(urn)) {
- throw new IllegalArgumentException(String.format("URN '%s' does not match a valid URN pattern.", urn));
- }
- }
-
- private boolean parseBuMam(@NonNull String urn) {
- Matcher matcher;
- matcher = PATTERN_BUMAM.matcher(urn);
- if (matcher.matches()) {
- bu = matcher.group(1).toLowerCase(Locale.US);
- assetType = matcher.group(2).toLowerCase(Locale.US);
-
- if (assetType.equals(ASSET_GROUP)) {
- // is a synonym of show (used in search request URN)
- assetType = ASSET_SHOW;
- }
-
- id = matcher.group(3); // Do not transform ID since it is case-sensitive.
- underlying = "urn:" + bu + ":" + assetType + ":" + id;
- return true;
- } else {
- return false;
- }
- }
-
- private boolean parseSwissTxt(@NonNull String urn) {
- Matcher matcher = PATTERN_SWISSTXT.matcher(urn);
- if (matcher.matches()) {
- String swisstxt = matcher.group(1).toLowerCase(Locale.US);
- bu = matcher.group(3).toLowerCase(Locale.US);
- assetType = matcher.group(2).toLowerCase(Locale.US);
- if (assetType.equals(ASSET_GROUP)) {
- // is a synonym of show (used in search request URN)
- assetType = ASSET_SHOW;
- }
- id = matcher.group(4);
- underlying = "urn:" + swisstxt + ":" + assetType + ":" + bu + ":" + id;
- return true;
- } else {
- return false;
- }
- }
-
- public IlUrn(@Nullable String bu, @Nullable String assetType, @Nullable String id) {
- this.bu = bu == null ? "default" : bu;
- this.assetType = assetType;
- this.id = id;
- underlying = "urn:" + this.bu + ":" + this.assetType + ":" + this.id;
- }
-
- /**
- * @param string potential URN
- * @return true iff a valid urn (false if string is null)
- */
- public static boolean isUrn(@Nullable String string) {
- return string != null && (PATTERN_BUMAM.matcher(string).matches() || PATTERN_SWISSTXT.matcher(string).matches());
- }
-
-
- public static String format(String bu, String assetType, String id) {
- return String.format("urn:%s:%s:%s", bu, assetType, id);
- }
-
- /**
- * Returns Business Unit.
- */
- public String getBu() {
- return bu;
- }
-
- /**
- * Return Asset Type (either audio or video)
- */
- public String getAssetType() {
- return assetType;
- }
-
- /**
- * Return ID
- */
- public String getId() {
- return id;
- }
-
- /**
- * Returns the underlying string representation.
- */
- @NonNull
- @Override
- public String toString() {
- return underlying;
- }
-
- public boolean isAudio() {
- return TextUtils.equals(ASSET_AUDIO, assetType);
- }
-
- public boolean isVideo() {
- return TextUtils.equals(ASSET_VIDEO, assetType) || TextUtils.equals(ASSET_VIDEO_SET, assetType);
- }
-
- /**
- * @param urn urn can be any media identifier, valid or not
- * @return true if urn is valid and of video type
- */
- public static boolean isAudio(@Nullable String urn) {
- return isUrn(urn) && new IlUrn(urn).isAudio();
- }
-
- /**
- * @param urn urn can be any media identifier, valid or not
- * @return true if urn is valid and of video type
- */
- public static boolean isVideo(@Nullable String urn) {
- return isUrn(urn) && new IlUrn(urn).isVideo();
- }
-
- public boolean isShow() {
- return TextUtils.equals(ASSET_SHOW, assetType);
- }
-
-
- public boolean equalsToString(@NonNull String o) {
- try {
- return underlying.equals(new IlUrn(o).toString());
- } catch (IllegalArgumentException invalidUrnException) {
- return false;
- }
- }
-
- /**
- * Get Id for given urn string.
- *
- * @param urn urn can be any media identifier, valid or not
- * @return id or full string if unparseable URN
- */
- public static String getId(@Nullable String urn) {
- return isUrn(urn) ? new IlUrn(urn).getId() : urn;
- }
-
- /**
- * Get Asset Type for given urn string.
- *
- * @param urn urn can be any media identifier, valid or not
- * @return assetType or "tv" if unparseable URN
- */
- public static String getAssetType(@Nullable String urn) {
- return isUrn(urn) ? new IlUrn(urn).getAssetType() : ASSET_VIDEO;
- }
-}
diff --git a/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/utils/IlUrn.kt b/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/utils/IlUrn.kt
new file mode 100644
index 0000000..4e9ec12
--- /dev/null
+++ b/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/utils/IlUrn.kt
@@ -0,0 +1,178 @@
+package ch.srg.dataProvider.integrationlayer.utils
+
+import java.util.regex.Pattern
+
+/**
+ * This very simple class represents a URN provided by the IL.
+ */
+class IlUrn private constructor() {
+ private var underlying: String? = null
+
+ /**
+ * Returns Business Unit.
+ */
+ var bu: String? = null
+ private set
+
+ /**
+ * Return Asset Type (either audio or video)
+ */
+ var assetType: String? = null
+ private set
+
+ /**
+ * Return ID
+ */
+ var id: String? = null
+ private set
+
+ val isAudio: Boolean
+ get() = assetType == ASSET_AUDIO
+
+ val isVideo: Boolean
+ get() = assetType == ASSET_VIDEO || assetType == ASSET_VIDEO_SET
+
+ val isShow: Boolean
+ get() = assetType == ASSET_SHOW
+
+ /**
+ * @param urn urn can be any media identifier, valid or not
+ * @throws IllegalArgumentException if not a valid urn
+ */
+ @Throws(IllegalArgumentException::class)
+ constructor(urn: String) : this() {
+ require(parseBuMam(urn) || parseSwissTxt(urn)) {
+ "URN '$urn' does not match a valid URN pattern."
+ }
+ }
+
+ constructor(bu: String?, assetType: String?, id: String?) : this() {
+ this.bu = bu ?: "default"
+ this.assetType = assetType
+ this.id = id
+
+ underlying = "urn:" + this.bu + ":" + this.assetType + ":" + this.id
+ }
+
+ fun equalsToString(other: String): Boolean {
+ return try {
+ underlying == IlUrn(other).toString()
+ } catch (_: IllegalArgumentException) {
+ false
+ }
+ }
+
+ override fun toString(): String {
+ return underlying.orEmpty()
+ }
+
+ @Suppress("MagicNumber")
+ private fun parseBuMam(urn: String): Boolean {
+ val matcher = PATTERN_BUMAM.matcher(urn)
+ if (matcher.matches()) {
+ bu = matcher.group(1)?.lowercase()
+ assetType = matcher.group(2)?.lowercase()
+ id = matcher.group(3) // Do not transform ID since it is case-sensitive.
+
+ if (assetType == ASSET_GROUP) {
+ // Is a synonym of show (used in search request URN)
+ assetType = ASSET_SHOW
+ }
+
+ underlying = "urn:$bu:$assetType:$id"
+
+ return true
+ } else {
+ return false
+ }
+ }
+
+ @Suppress("MagicNumber")
+ private fun parseSwissTxt(urn: String): Boolean {
+ val matcher = PATTERN_SWISSTXT.matcher(urn)
+ if (matcher.matches()) {
+ val swissTxt = matcher.group(1)?.lowercase()
+ bu = matcher.group(3)?.lowercase()
+ assetType = matcher.group(2)?.lowercase()
+ id = matcher.group(4)
+
+ if (assetType == ASSET_GROUP) {
+ // Is a synonym of show (used in search request URN)
+ assetType = ASSET_SHOW
+ }
+
+ underlying = "urn:$swissTxt:$assetType:$bu:$id"
+
+ return true
+ } else {
+ return false
+ }
+ }
+
+ companion object {
+ const val ASSET_VIDEO = "video"
+ const val ASSET_VIDEO_SET = "videoset"
+ const val ASSET_AUDIO = "audio"
+ const val ASSET_SHOW = "show"
+ const val ASSET_GROUP = "assetgroup"
+
+ private val PATTERN_BUMAM =
+ "^urn:(srf|rts|rsi|rtr|swi|default):(?:[^:]+:)?(video|audio|videoset|show|assetgroup):([^:]+)$".toPattern(Pattern.CASE_INSENSITIVE)
+ private val PATTERN_SWISSTXT =
+ "^urn:(swisstxt):(?:[^:]+:)?(video|audio|videoset|show|assetgroup):(srf|rts|rsi|rtr|swi):([^:]+)$".toPattern(Pattern.CASE_INSENSITIVE)
+
+ /**
+ * @param string potential URN
+ * @return true iff a valid urn (false if string is null)
+ */
+ @JvmStatic
+ fun isUrn(string: String?): Boolean {
+ return string != null && (PATTERN_BUMAM.matcher(string).matches() || PATTERN_SWISSTXT.matcher(string).matches())
+ }
+
+ @JvmStatic
+ fun format(bu: String?, assetType: String?, id: String?): String {
+ return "urn:$bu:$assetType:$id"
+ }
+
+ /**
+ * @param urn urn can be any media identifier, valid or not
+ * @return true if urn is valid and of video type
+ */
+ @JvmStatic
+ fun isAudio(urn: String?): Boolean {
+ return urn != null && isUrn(urn) && IlUrn(urn).isAudio
+ }
+
+ /**
+ * @param urn urn can be any media identifier, valid or not
+ * @return true if urn is valid and of video type
+ */
+ @JvmStatic
+ fun isVideo(urn: String?): Boolean {
+ return urn != null && isUrn(urn) && IlUrn(urn).isVideo
+ }
+
+ /**
+ * Get Id for given urn string.
+ *
+ * @param urn urn can be any media identifier, valid or not
+ * @return id or full string if unparseable URN
+ */
+ @JvmStatic
+ fun getId(urn: String?): String? {
+ return if (urn != null && isUrn(urn)) IlUrn(urn).id else urn
+ }
+
+ /**
+ * Get Asset Type for given urn string.
+ *
+ * @param urn urn can be any media identifier, valid or not
+ * @return assetType or "tv" if unparseable URN
+ */
+ @JvmStatic
+ fun getAssetType(urn: String?): String? {
+ return if (urn != null && isUrn(urn)) IlUrn(urn).assetType else ASSET_VIDEO
+ }
+ }
+}
diff --git a/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/utils/StreamComparator.java b/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/utils/StreamComparator.java
deleted file mode 100644
index 2b6c1a9..0000000
--- a/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/utils/StreamComparator.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package ch.srg.dataProvider.integrationlayer.utils;
-
-import androidx.annotation.Nullable;
-
-import java.util.Comparator;
-import java.util.List;
-
-import ch.srg.dataProvider.integrationlayer.data.remote.Quality;
-import ch.srg.dataProvider.integrationlayer.data.remote.Resource;
-import ch.srg.dataProvider.integrationlayer.data.remote.StreamingMethod;
-
-/**
- * Copyright (c) SRG SSR. All rights reserved.
- *
- * License information is available from the LICENSE file.
- */
-public class StreamComparator implements Comparator {
- private static final int HANDICAP_STREAMING = 1000;
- private static final int HANDICAP_DVR = 10;
- private static final int HANDICAP_QUALITY = 1;
-
- public static final int SCORE_NOT_SUPPORTED = Integer.MAX_VALUE;
-
- private final List orderedQualities;
- private final List orderedStreaming;
- @Nullable
- private final List supportedDrms;
- private final boolean dvrSupported;
-
- public StreamComparator(List orderedQualities, List orderedStreaming, @Nullable List supportedDrms, boolean dvrSupported) {
- this.orderedQualities = orderedQualities;
- this.orderedStreaming = orderedStreaming;
- this.supportedDrms = supportedDrms;
- this.dvrSupported = dvrSupported;
- }
-
- @Override
- public int compare(Resource lhs, Resource rhs) {
- int l = score(lhs);
- int r = score(rhs);
- //noinspection UseCompareMethod
- return l == r ? 0 : ((l > r) ? 1 : -1);
- }
-
- public int score(Resource r) {
- if (r.getStreamingMethod() == null
- || (!dvrSupported && r.getDvr())
- || (!isSupportedDrm(r.getDrmList()))) {
- return SCORE_NOT_SUPPORTED;
- }
- int indexOfStreaming = orderedStreaming.indexOf(r.getStreamingMethod()); // will return -1 if not in the list
- int indexOfQuality = orderedQualities.indexOf(r.getQuality()); // will return -1 if not in the list
-
- return (indexOfStreaming < 0 ? orderedStreaming.size() : indexOfStreaming) * HANDICAP_STREAMING
- + (indexOfQuality < 0 ? orderedQualities.size() : indexOfQuality) * HANDICAP_QUALITY
- + (r.getDvr() ? 0 : HANDICAP_DVR);
- }
-
- private boolean isSupportedDrm(List drmList) {
- if (drmList == null) {
- return true;
- }
- if (supportedDrms != null) {
- for (Resource.Drm drm : drmList) {
- if (supportedDrms.contains(drm.getType())) {
- return true;
- }
- }
- }
- return false;
- }
-}
diff --git a/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/utils/StreamComparator.kt b/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/utils/StreamComparator.kt
new file mode 100644
index 0000000..3151796
--- /dev/null
+++ b/dataprovider-retrofit/src/main/java/ch/srg/dataProvider/integrationlayer/utils/StreamComparator.kt
@@ -0,0 +1,58 @@
+package ch.srg.dataProvider.integrationlayer.utils
+
+import ch.srg.dataProvider.integrationlayer.data.remote.Quality
+import ch.srg.dataProvider.integrationlayer.data.remote.Resource
+import ch.srg.dataProvider.integrationlayer.data.remote.StreamingMethod
+
+/**
+ * Copyright (c) SRG SSR. All rights reserved.
+ *
+ * License information is available from the LICENSE file.
+ */
+class StreamComparator(
+ private val orderedQualities: List,
+ private val orderedStreaming: List,
+ private val supportedDrms: List?,
+ private val dvrSupported: Boolean,
+) : Comparator {
+ override fun compare(lhs: Resource, rhs: Resource): Int {
+ val l = score(lhs)
+ val r = score(rhs)
+
+ return l.compareTo(r)
+ }
+
+ fun score(resource: Resource): Int {
+ if ((!dvrSupported && resource.dvr) || (!isSupportedDrm(resource.drmList))) {
+ return SCORE_NOT_SUPPORTED
+ }
+
+ val indexOfStreaming = orderedStreaming.indexOf(resource.streamingMethod) // Will return -1 if not in the list
+ val indexOfQuality = orderedQualities.indexOf(resource.quality) // Will return -1 if not in the list
+ val scoreStreaming = (if (indexOfStreaming < 0) orderedStreaming.size else indexOfStreaming) * HANDICAP_STREAMING
+ val scoreQuality = (if (indexOfQuality < 0) orderedQualities.size else indexOfQuality) * HANDICAP_QUALITY
+ val scoreDvr = if (resource.dvr) 0 else HANDICAP_DVR
+
+ return scoreStreaming + scoreQuality + scoreDvr
+ }
+
+ private fun isSupportedDrm(drmList: List?): Boolean {
+ if (drmList == null) {
+ return true
+ }
+
+ if (supportedDrms.isNullOrEmpty()) {
+ return false
+ }
+
+ return drmList.any { it.type in supportedDrms }
+ }
+
+ companion object {
+ const val SCORE_NOT_SUPPORTED = Int.MAX_VALUE
+
+ private const val HANDICAP_STREAMING = 1000
+ private const val HANDICAP_DVR = 10
+ private const val HANDICAP_QUALITY = 1
+ }
+}
diff --git a/dataprovider-retrofit/src/test/java/ch/srg/dataProvider/integrationlayer/utils/MediaFetcherInputs.kt b/dataprovider-retrofit/src/test/java/ch/srg/dataProvider/integrationlayer/utils/MediaFetcherInputs.kt
new file mode 100644
index 0000000..47da78f
--- /dev/null
+++ b/dataprovider-retrofit/src/test/java/ch/srg/dataProvider/integrationlayer/utils/MediaFetcherInputs.kt
@@ -0,0 +1,42 @@
+package ch.srg.dataProvider.integrationlayer.utils
+
+import ch.srg.dataProvider.integrationlayer.data.remote.Quality
+import ch.srg.dataProvider.integrationlayer.data.remote.Resource
+import ch.srg.dataProvider.integrationlayer.data.remote.StreamingMethod
+
+/**
+ * Copyright (c) SRG SSR. All rights reserved.
+ *
+ *
+ * License information is available from the LICENSE file.
+ */
+object MediaFetcherInputs {
+ @JvmField
+ @Transient
+ val STREAMING_ORDER_DEFAULT: List = listOf(
+ StreamingMethod.DASH,
+ StreamingMethod.HLS,
+ StreamingMethod.PROGRESSIVE
+ )
+
+ @Transient
+ val DRM_TYPES: List = listOf(
+ Resource.Drm.Type.WIDEVINE, Resource.Drm.Type.PLAYREADY
+ )
+
+ @JvmField
+ @Transient
+ val QUALITY_ORDER: List = listOf(
+ Quality.SD,
+ Quality.HQ,
+ Quality.HD
+ )
+
+ @JvmField
+ @Transient
+ val QUALITY_ORDER_HD: List = listOf(
+ Quality.HD,
+ Quality.HQ,
+ Quality.SD
+ )
+}
diff --git a/dataprovider-retrofit/src/test/java/ch/srg/dataProvider/integrationlayer/utils/ResourceBuilder.kt b/dataprovider-retrofit/src/test/java/ch/srg/dataProvider/integrationlayer/utils/ResourceBuilder.kt
new file mode 100644
index 0000000..e4126a3
--- /dev/null
+++ b/dataprovider-retrofit/src/test/java/ch/srg/dataProvider/integrationlayer/utils/ResourceBuilder.kt
@@ -0,0 +1,31 @@
+package ch.srg.dataProvider.integrationlayer.utils
+
+import ch.srg.dataProvider.integrationlayer.data.remote.Quality
+import ch.srg.dataProvider.integrationlayer.data.remote.Resource
+import ch.srg.dataProvider.integrationlayer.data.remote.Resource.Drm
+import ch.srg.dataProvider.integrationlayer.data.remote.StreamingMethod
+
+/**
+ * Copyright (c) SRG SSR. All rights reserved.
+ *
+ * License information is available from the LICENSE file.
+ */
+object ResourceBuilder {
+ fun createResourceFrom(
+ url: String,
+ quality: Quality,
+ streaming: StreamingMethod,
+ live: Boolean,
+ dvr: Boolean,
+ vararg drmTypes: Drm.Type
+ ): Resource {
+ var drmList: MutableList? = null
+ if (drmTypes.isNotEmpty()) {
+ drmList = ArrayList()
+ for (type in drmTypes) {
+ drmList.add(Drm(type, "license", null))
+ }
+ }
+ return Resource(url = url, quality = quality, streamingMethod = streaming, live = live, dvr = dvr, drmList = drmList)
+ }
+}
diff --git a/dataprovider-retrofit/src/test/java/ch/srg/dataProvider/integrationlayer/utils/StreamComparatorAllPossibilitiesTest.kt b/dataprovider-retrofit/src/test/java/ch/srg/dataProvider/integrationlayer/utils/StreamComparatorAllPossibilitiesTest.kt
new file mode 100644
index 0000000..16a4648
--- /dev/null
+++ b/dataprovider-retrofit/src/test/java/ch/srg/dataProvider/integrationlayer/utils/StreamComparatorAllPossibilitiesTest.kt
@@ -0,0 +1,224 @@
+package ch.srg.dataProvider.integrationlayer.utils
+
+import ch.srg.dataProvider.integrationlayer.data.remote.Quality
+import ch.srg.dataProvider.integrationlayer.data.remote.Resource
+import ch.srg.dataProvider.integrationlayer.data.remote.StreamingMethod
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import java.util.Collections
+
+/**
+ * Copyright (c) SRG SSR. All rights reserved.
+ *
+ *
+ * License information is available from the LICENSE file.
+ */
+@RunWith(Parameterized::class)
+class StreamComparatorAllPossibilitiesTest(
+ private val qualitiesOrder: List,
+ private val streamingOrder: List,
+ private val dvrSupport: Boolean,
+ private val drmSupported: Boolean,
+ private val expectedResource: ExpectedResult,
+) {
+
+ class ExpectedResult(val quality: Quality, val streaming: StreamingMethod, val drmType: Resource.Drm.Type?, val dvr: Boolean) {
+ constructor(quality: Quality, streaming: StreamingMethod, dvr: Boolean) : this(quality, streaming, null, dvr)
+ }
+
+ @Test
+ fun firstDashHdDrmFirstDvr() {
+ val comparator = StreamComparator(qualitiesOrder, streamingOrder, if (drmSupported) MediaFetcherInputs.DRM_TYPES else null, dvrSupport)
+ val listResource = listAllPossibilities()
+ sortAndPrint(comparator, listResource)
+ val r = listResource[0]
+
+ checkResource(r, expectedResource)
+ }
+
+ private fun checkResource(r: Resource, expectedResult: ExpectedResult) {
+ Assert.assertNotNull(r.streamingMethod)
+ Assert.assertNotNull(r.quality)
+ Assert.assertEquals(expectedResult.streaming, r.streamingMethod)
+ Assert.assertEquals(expectedResult.quality, r.quality)
+ Assert.assertEquals("hasDrm", expectedResult.drmType != null, r.hasDrm())
+ r.drmList?.let {
+ Assert.assertTrue(it.contains(createDrm(Resource.Drm.Type.WIDEVINE)))
+ }
+
+ Assert.assertEquals("dvr", expectedResult.dvr, r.dvr)
+ }
+
+ private fun listAllPossibilities(): List {
+ val resourceList: MutableList = ArrayList()
+ // StreamComparator keep order in the resource list regarding to DRM situation.
+ resourceList.add(
+ ResourceBuilder.createResourceFrom(
+ "hd_hls_drm_ios",
+ Quality.HD,
+ StreamingMethod.HLS,
+ true,
+ true,
+ Resource.Drm.Type.FAIRPLAY
+ )
+ )
+
+ resourceList.add(
+ ResourceBuilder.createResourceFrom(
+ "sd_dash_drm",
+ Quality.SD,
+ StreamingMethod.DASH,
+ true,
+ false,
+ Resource.Drm.Type.PLAYREADY,
+ Resource.Drm.Type.WIDEVINE
+ )
+ )
+ resourceList.add(
+ ResourceBuilder.createResourceFrom(
+ "sd_dash_drm_dvr",
+ Quality.SD,
+ StreamingMethod.DASH,
+ true,
+ true,
+ Resource.Drm.Type.PLAYREADY,
+ Resource.Drm.Type.WIDEVINE
+ )
+ )
+ resourceList.add(
+ ResourceBuilder.createResourceFrom(
+ "hd_dash_drm",
+ Quality.HD,
+ StreamingMethod.DASH,
+ true,
+ false,
+ Resource.Drm.Type.PLAYREADY,
+ Resource.Drm.Type.WIDEVINE
+ )
+ )
+ resourceList.add(
+ ResourceBuilder.createResourceFrom(
+ "hd_dash_drm_dvr",
+ Quality.HD,
+ StreamingMethod.DASH,
+ true,
+ true,
+ Resource.Drm.Type.PLAYREADY,
+ Resource.Drm.Type.WIDEVINE
+ )
+ )
+ resourceList.add(ResourceBuilder.createResourceFrom("sd_progressive", Quality.SD, StreamingMethod.PROGRESSIVE, true, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("sd_progressive_dvr", Quality.SD, StreamingMethod.PROGRESSIVE, true, true))
+ resourceList.add(ResourceBuilder.createResourceFrom("hd_progressive", Quality.HD, StreamingMethod.PROGRESSIVE, true, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("hd_progressive_dvr", Quality.HD, StreamingMethod.PROGRESSIVE, true, true))
+
+ resourceList.add(ResourceBuilder.createResourceFrom("sd_dash", Quality.SD, StreamingMethod.DASH, true, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("sd_dash_dvr", Quality.SD, StreamingMethod.DASH, true, true))
+ resourceList.add(ResourceBuilder.createResourceFrom("hd_dash", Quality.HD, StreamingMethod.DASH, true, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("hd_dash_dvr", Quality.HD, StreamingMethod.DASH, true, true))
+
+ resourceList.add(ResourceBuilder.createResourceFrom("sd_hls", Quality.SD, StreamingMethod.HLS, true, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("sd_hls_dvr", Quality.SD, StreamingMethod.HLS, true, true))
+ resourceList.add(ResourceBuilder.createResourceFrom("hd_hls", Quality.HD, StreamingMethod.HLS, true, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("hd_hls_dvr", Quality.HD, StreamingMethod.HLS, true, true))
+
+ return resourceList
+ }
+
+
+ private fun sortAndPrint(comparator: StreamComparator, resourceList: List) {
+ Collections.sort(resourceList, comparator)
+ for (r in resourceList) {
+ println(r.url + " -> " + comparator.score(r))
+ }
+ }
+
+ companion object {
+ var WITH_DVR: Boolean = true
+ var NO_DVR: Boolean = false
+ var WITH_DRM: Boolean = true
+ var NO_DRM: Boolean = false
+
+ var HLS_FIRST: List = listOf(StreamingMethod.HLS, StreamingMethod.DASH, StreamingMethod.PROGRESSIVE)
+
+ @JvmStatic
+ @Parameterized.Parameters
+ fun parameters(): Iterable> {
+ return listOf(
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER_HD, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, NO_DVR, WITH_DRM,
+ ExpectedResult(Quality.HD, StreamingMethod.DASH, Resource.Drm.Type.WIDEVINE, NO_DVR)
+ ),
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER_HD, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, WITH_DVR, WITH_DRM,
+ ExpectedResult(Quality.HD, StreamingMethod.DASH, Resource.Drm.Type.WIDEVINE, WITH_DVR)
+ ),
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, WITH_DVR, WITH_DRM,
+ ExpectedResult(Quality.SD, StreamingMethod.DASH, Resource.Drm.Type.WIDEVINE, WITH_DVR)
+ ),
+
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER_HD, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, NO_DVR, WITH_DRM,
+ ExpectedResult(Quality.HD, StreamingMethod.DASH, Resource.Drm.Type.WIDEVINE, NO_DVR)
+ ),
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, NO_DVR, WITH_DRM,
+ ExpectedResult(Quality.SD, StreamingMethod.DASH, Resource.Drm.Type.WIDEVINE, NO_DVR)
+ ),
+
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER_HD, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, NO_DVR, NO_DRM,
+ ExpectedResult(Quality.HD, StreamingMethod.DASH, NO_DVR)
+ ),
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, NO_DVR, NO_DRM,
+ ExpectedResult(Quality.SD, StreamingMethod.DASH, NO_DVR)
+ ),
+
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER_HD, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, WITH_DVR, NO_DRM,
+ ExpectedResult(Quality.HD, StreamingMethod.DASH, WITH_DVR)
+ ),
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, WITH_DVR, NO_DRM,
+ ExpectedResult(Quality.SD, StreamingMethod.DASH, WITH_DVR)
+ ),
+
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER_HD, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, NO_DVR, WITH_DRM,
+ ExpectedResult(Quality.HD, StreamingMethod.DASH, Resource.Drm.Type.WIDEVINE, NO_DVR)
+ ),
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, NO_DVR, WITH_DRM,
+ ExpectedResult(Quality.SD, StreamingMethod.DASH, Resource.Drm.Type.WIDEVINE, NO_DVR)
+ ),
+
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER_HD, HLS_FIRST, NO_DVR, NO_DRM,
+ ExpectedResult(Quality.HD, StreamingMethod.HLS, NO_DVR)
+ ),
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER, HLS_FIRST, NO_DVR, NO_DRM,
+ ExpectedResult(Quality.SD, StreamingMethod.HLS, NO_DVR)
+ ), // no drm type because no HLS resources with Widevine
+
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER_HD, HLS_FIRST, NO_DVR, WITH_DRM,
+ ExpectedResult(Quality.HD, StreamingMethod.HLS, null, NO_DVR)
+ ),
+ arrayOf(
+ MediaFetcherInputs.QUALITY_ORDER, HLS_FIRST, NO_DVR, WITH_DRM,
+ ExpectedResult(Quality.SD, StreamingMethod.HLS, null, NO_DVR)
+ ),
+ )
+ }
+
+ private fun createDrm(type: Resource.Drm.Type): Resource.Drm {
+ return Resource.Drm(type, "license", null)
+ }
+
+ }
+}
diff --git a/dataprovider-retrofit/src/test/java/ch/srg/dataProvider/integrationlayer/utils/StreamComparatorTest.kt b/dataprovider-retrofit/src/test/java/ch/srg/dataProvider/integrationlayer/utils/StreamComparatorTest.kt
new file mode 100644
index 0000000..7707e22
--- /dev/null
+++ b/dataprovider-retrofit/src/test/java/ch/srg/dataProvider/integrationlayer/utils/StreamComparatorTest.kt
@@ -0,0 +1,208 @@
+package ch.srg.dataProvider.integrationlayer.utils
+
+import ch.srg.dataProvider.integrationlayer.data.remote.Quality
+import ch.srg.dataProvider.integrationlayer.data.remote.Resource
+import ch.srg.dataProvider.integrationlayer.data.remote.StreamingMethod
+import org.junit.Assert
+import org.junit.Test
+import java.util.Arrays
+import java.util.Collections
+
+/**
+ * Copyright (c) SRG SSR. All rights reserved.
+ *
+ *
+ * License information is available from the LICENSE file.
+ */
+class StreamComparatorTest {
+ @Test
+ fun streamOrderWithUncompleteStreamingOrderList() {
+ val listStreamingOrder: List = listOf(StreamingMethod.DASH, StreamingMethod.HLS)
+ val comparator = StreamComparator(MediaFetcherInputs.QUALITY_ORDER, listStreamingOrder, null, true)
+
+ val resourceList: MutableList = ArrayList()
+ resourceList.add(ResourceBuilder.createResourceFrom("1", Quality.HD, StreamingMethod.PROGRESSIVE, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("2", Quality.HD, StreamingMethod.HLS, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("3", Quality.HD, StreamingMethod.DASH, false, false))
+ sortAndPrint(comparator, resourceList)
+ Assert.assertEquals(resourceList[0].streamingMethod, StreamingMethod.DASH)
+
+ val resourceList1: MutableList = ArrayList()
+ resourceList1.add(ResourceBuilder.createResourceFrom("2", Quality.HD, StreamingMethod.HLS, false, false))
+ resourceList1.add(ResourceBuilder.createResourceFrom("1", Quality.HD, StreamingMethod.PROGRESSIVE, false, false))
+ resourceList1.add(ResourceBuilder.createResourceFrom("3", Quality.HD, StreamingMethod.DASH, false, false))
+ sortAndPrint(comparator, resourceList1)
+ Assert.assertEquals(resourceList1[0].streamingMethod, StreamingMethod.DASH)
+
+ val resourceList2: MutableList = ArrayList()
+ resourceList2.add(ResourceBuilder.createResourceFrom("3", Quality.HD, StreamingMethod.DASH, false, false))
+ resourceList2.add(ResourceBuilder.createResourceFrom("1", Quality.HD, StreamingMethod.PROGRESSIVE, false, false))
+ resourceList2.add(ResourceBuilder.createResourceFrom("2", Quality.HD, StreamingMethod.HLS, false, false))
+ sortAndPrint(comparator, resourceList2)
+ Assert.assertEquals(resourceList2[0].streamingMethod, StreamingMethod.DASH)
+ }
+
+ @Test
+ fun streamOrderWithUncompleteQualityOrderList() {
+ val listQualityOrder = Arrays.asList(Quality.HD, Quality.SD)
+ val comparator = StreamComparator(listQualityOrder, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, null, true)
+
+ val resourceList: MutableList = ArrayList()
+ resourceList.add(ResourceBuilder.createResourceFrom("1", Quality.HQ, StreamingMethod.DASH, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("2", Quality.SD, StreamingMethod.DASH, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("3", Quality.HD, StreamingMethod.DASH, false, false))
+ sortAndPrint(comparator, resourceList)
+ Assert.assertEquals(resourceList[0].quality, Quality.HD)
+
+ val resourceList1: MutableList = ArrayList()
+ resourceList1.add(ResourceBuilder.createResourceFrom("2", Quality.SD, StreamingMethod.DASH, false, false))
+ resourceList1.add(ResourceBuilder.createResourceFrom("1", Quality.HQ, StreamingMethod.DASH, false, false))
+ resourceList1.add(ResourceBuilder.createResourceFrom("3", Quality.HD, StreamingMethod.DASH, false, false))
+ sortAndPrint(comparator, resourceList1)
+ Assert.assertEquals(resourceList1[0].quality, Quality.HD)
+
+ val resourceList2: MutableList = ArrayList()
+ resourceList2.add(ResourceBuilder.createResourceFrom("3", Quality.HD, StreamingMethod.DASH, false, false))
+ resourceList2.add(ResourceBuilder.createResourceFrom("1", Quality.HQ, StreamingMethod.DASH, false, false))
+ resourceList2.add(ResourceBuilder.createResourceFrom("2", Quality.SD, StreamingMethod.DASH, false, false))
+ sortAndPrint(comparator, resourceList2)
+ Assert.assertEquals(resourceList2[0].quality, Quality.HD)
+ Assert.assertEquals(resourceList2[1].quality, Quality.SD)
+ }
+
+ @Test
+ fun dashFirst() {
+ val comparator = StreamComparator(MediaFetcherInputs.QUALITY_ORDER, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, null, false)
+
+ val resourceList: MutableList = ArrayList()
+ resourceList.add(ResourceBuilder.createResourceFrom("1", Quality.HD, StreamingMethod.PROGRESSIVE, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("2", Quality.HD, StreamingMethod.HLS, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("4", Quality.SD, StreamingMethod.PROGRESSIVE, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("3", Quality.HD, StreamingMethod.DASH, false, false))
+
+ sortAndPrint(comparator, resourceList)
+ Assert.assertEquals(resourceList[0].streamingMethod, StreamingMethod.DASH)
+ }
+
+ @Test
+ fun hlsFirstWhenNoDash() {
+ val comparator = StreamComparator(
+ MediaFetcherInputs.QUALITY_ORDER_HD, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, MediaFetcherInputs
+ .DRM_TYPES, false
+ )
+
+ val resourceList: MutableList = ArrayList()
+ resourceList.add(ResourceBuilder.createResourceFrom("3", Quality.SD, StreamingMethod.PROGRESSIVE, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("1", Quality.HD, StreamingMethod.PROGRESSIVE, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("2", Quality.HD, StreamingMethod.HLS, false, false))
+
+ sortAndPrint(comparator, resourceList)
+ Assert.assertEquals(resourceList[0].streamingMethod, StreamingMethod.HLS)
+ }
+
+ @Test
+ fun unsupportedDvr() {
+ val comparator = StreamComparator(MediaFetcherInputs.QUALITY_ORDER, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, null, false)
+
+ val resourceList: MutableList = ArrayList()
+ resourceList.add(ResourceBuilder.createResourceFrom("1", Quality.HD, StreamingMethod.DASH, false, true))
+ resourceList.add(ResourceBuilder.createResourceFrom("2", Quality.HD, StreamingMethod.HLS, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("3", Quality.HD, StreamingMethod.DASH, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("4", Quality.SD, StreamingMethod.PROGRESSIVE, false, false))
+ sortAndPrint(comparator, resourceList)
+ Assert.assertEquals("3", resourceList[0].url)
+
+ val resourceList2: MutableList = ArrayList()
+ resourceList2.add(ResourceBuilder.createResourceFrom("1", Quality.HD, StreamingMethod.DASH, false, true))
+ resourceList2.add(ResourceBuilder.createResourceFrom("2", Quality.HD, StreamingMethod.HLS, false, false))
+ resourceList2.add(ResourceBuilder.createResourceFrom("4", Quality.SD, StreamingMethod.PROGRESSIVE, false, false))
+ sortAndPrint(comparator, resourceList2)
+ Assert.assertEquals("2", resourceList2[0].url)
+ }
+
+ @Test
+ fun unsupportedDvrWithDrmFirst() {
+ val comparator = StreamComparator(MediaFetcherInputs.QUALITY_ORDER, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, null, false)
+
+ val resourceList: MutableList = ArrayList()
+ resourceList.add(ResourceBuilder.createResourceFrom("1", Quality.HD, StreamingMethod.DASH, false, true))
+ resourceList.add(ResourceBuilder.createResourceFrom("2", Quality.HD, StreamingMethod.HLS, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("3", Quality.HD, StreamingMethod.DASH, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("4", Quality.SD, StreamingMethod.PROGRESSIVE, false, false))
+ sortAndPrint(comparator, resourceList)
+ Assert.assertEquals("3", resourceList[0].url)
+
+ val resourceList2: MutableList = ArrayList()
+ resourceList2.add(ResourceBuilder.createResourceFrom("1", Quality.HD, StreamingMethod.DASH, false, true))
+ resourceList2.add(ResourceBuilder.createResourceFrom("2", Quality.HD, StreamingMethod.HLS, false, false))
+ resourceList2.add(ResourceBuilder.createResourceFrom("4", Quality.SD, StreamingMethod.PROGRESSIVE, false, false))
+ sortAndPrint(comparator, resourceList2)
+ Assert.assertEquals("2", resourceList2[0].url)
+ }
+
+ @Test
+ fun unsupportedDrm() {
+ val comparator = StreamComparator(MediaFetcherInputs.QUALITY_ORDER, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, null, false)
+
+ val resourceList: MutableList = ArrayList()
+ resourceList.add(ResourceBuilder.createResourceFrom("1", Quality.HD, StreamingMethod.DASH, false, false, Resource.Drm.Type.FAIRPLAY))
+ resourceList.add(ResourceBuilder.createResourceFrom("2", Quality.HD, StreamingMethod.HLS, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("3", Quality.HD, StreamingMethod.DASH, false, false))
+ resourceList.add(ResourceBuilder.createResourceFrom("4", Quality.SD, StreamingMethod.PROGRESSIVE, false, false))
+ sortAndPrint(comparator, resourceList)
+ Assert.assertEquals("3", resourceList[0].url)
+
+ val resourceList2: MutableList = ArrayList()
+ resourceList2.add(ResourceBuilder.createResourceFrom("1", Quality.HD, StreamingMethod.DASH, false, false, Resource.Drm.Type.FAIRPLAY))
+ resourceList2.add(ResourceBuilder.createResourceFrom("2", Quality.HD, StreamingMethod.HLS, false, false))
+ resourceList2.add(ResourceBuilder.createResourceFrom("4", Quality.SD, StreamingMethod.PROGRESSIVE, false, false))
+ sortAndPrint(comparator, resourceList2)
+ Assert.assertEquals("2", resourceList2[0].url)
+ }
+
+ @Test
+ fun nullStreamingType() {
+ val comparator = StreamComparator(MediaFetcherInputs.QUALITY_ORDER, MediaFetcherInputs.STREAMING_ORDER_DEFAULT, null, true)
+
+ val resourceList = listWithNullStreamingType()
+ sortAndPrint(comparator, resourceList)
+
+ Assert.assertNotEquals("null", resourceList[0].url)
+ }
+
+ private fun listWithNullStreamingType(): List {
+ val resourceList: MutableList = ArrayList()
+ resourceList.add(ResourceBuilder.createResourceFrom("hsl", Quality.HD, StreamingMethod.HLS, false, true))
+ resourceList.add(ResourceBuilder.createResourceFrom("hsl", Quality.HD, StreamingMethod.DASH, false, true))
+ resourceList.add(ResourceBuilder.createResourceFrom("drm_fairplay", Quality.HD, StreamingMethod.HLS, false, true, Resource.Drm.Type.FAIRPLAY))
+ resourceList.add(
+ ResourceBuilder.createResourceFrom(
+ "drm_playready",
+ Quality.HD,
+ StreamingMethod.DASH,
+ false,
+ true,
+ Resource.Drm.Type.PLAYREADY
+ )
+ )
+ resourceList.add(
+ ResourceBuilder.createResourceFrom(
+ "drm_widevine",
+ Quality.HD,
+ StreamingMethod.DASH,
+ false,
+ true,
+ Resource.Drm.Type.WIDEVINE
+ )
+ )
+ return resourceList
+ }
+
+ private fun sortAndPrint(comparator: StreamComparator, resourceList: List) {
+ Collections.sort(resourceList, comparator)
+ for (r in resourceList) {
+ println(r.url + " -> " + comparator.score(r))
+ }
+ }
+
+}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 22fc96f..1879561 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,7 +1,6 @@
[versions]
android-gradle-plugin = "8.6.0"
androidx-activity = "1.9.1"
-androidx-annotation = "1.8.2"
androidx-lifecycle = "2.8.4"
androidx-paging = "3.3.2"
androidx-test-ext-junit = "1.2.1"
@@ -15,7 +14,6 @@ robolectric = "4.13"
[libraries]
androidx-activity = { module = "androidx.activity:activity", version.ref = "androidx-activity" }
-androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidx-annotation" }
androidx-lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime", version.ref = "androidx-lifecycle" }
androidx-paging-common = { module = "androidx.paging:paging-common", version.ref = "androidx-paging" }
androidx-test-ext-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-test-ext-junit" }