From e536eeccab5d7ab6673426e01df0185f74749ff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Muller?= Date: Tue, 19 Nov 2024 07:44:08 +0100 Subject: [PATCH] Create an enum for IL location (#791) --- .../pillarbox/core/business/SRGMediaItem.kt | 20 +++++------ .../integrationlayer/service/IlLocation.kt | 33 +++++++++++++++++++ .../core/business/SRGMediaItemBuilderTest.kt | 13 ++++---- .../service/IlLocationTest.kt | 28 ++++++++++++++++ .../pillarbox/demo/shared/data/DemoItem.kt | 7 ++-- .../pillarbox/demo/shared/di/PlayerModule.kt | 9 ++--- .../srgssr/pillarbox/demo/MainNavigation.kt | 11 ++++--- .../demo/ui/examples/InsertContentView.kt | 2 +- .../pillarbox/demo/ui/lists/ListsHome.kt | 5 +-- 9 files changed, 96 insertions(+), 32 deletions(-) create mode 100644 pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/integrationlayer/service/IlLocation.kt create mode 100644 pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/integrationlayer/service/IlLocationTest.kt diff --git a/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/SRGMediaItem.kt b/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/SRGMediaItem.kt index 3c3cc7e7d..dfa58a0d9 100644 --- a/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/SRGMediaItem.kt +++ b/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/SRGMediaItem.kt @@ -9,6 +9,7 @@ import androidx.media3.common.MediaItem import androidx.media3.common.MediaMetadata import ch.srgssr.pillarbox.core.business.integrationlayer.data.isValidMediaUrn import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlHost +import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlLocation import ch.srgssr.pillarbox.core.business.integrationlayer.service.Vector import ch.srgssr.pillarbox.core.business.source.MimeTypeSrg import ch.srgssr.pillarbox.player.PillarboxDsl @@ -79,7 +80,7 @@ class SRGMediaItemBuilder internal constructor(mediaItem: MediaItem) { private var urn: String = mediaItem.mediaId private var host: URL = IlHost.DEFAULT private var forceSAM: Boolean = false - private var forceLocation: String? = null + private var ilLocation: IlLocation? = null private var vector: String = Vector.MOBILE init { @@ -91,7 +92,7 @@ class SRGMediaItemBuilder internal constructor(mediaItem: MediaItem) { uri.host?.let { hostname -> host = URL(Uri.Builder().scheme(host.protocol).authority(hostname).build().toString()) } this.urn = urn!! this.forceSAM = uri.getQueryParameter(PARAM_FORCE_SAM)?.toBooleanStrictOrNull() ?: false - this.forceLocation = uri.getQueryParameter(PARAM_FORCE_LOCATION) + this.ilLocation = uri.getQueryParameter(PARAM_FORCE_LOCATION)?.let { IlLocation.fromName(it) } uri.getQueryParameter(PARAM_VECTOR)?.let { vector = it } } } @@ -143,15 +144,12 @@ class SRGMediaItemBuilder internal constructor(mediaItem: MediaItem) { } /** - * Forces the location for IL/SAM backend calls. + * Sets the location for IL backend calls. * - * @param forceLocation The location to force. Valid values are: - * - `null`: disables forced location and uses automatic detection. - * - `"CH"`: forces the location to Switzerland. - * - `"WW"`: forces the location to Worldwide. + * @param ilLocation The location to set. Passing `null` defaults to automatic detection. */ - fun forceLocation(forceLocation: String?) { - this.forceLocation = forceLocation + fun ilLocation(ilLocation: IlLocation?) { + this.ilLocation = ilLocation } /** @@ -186,8 +184,8 @@ class SRGMediaItemBuilder internal constructor(mediaItem: MediaItem) { if (forceSAM) { appendQueryParameter(PARAM_FORCE_SAM, true.toString()) } - if (!forceLocation.isNullOrBlank()) { - appendQueryParameter(PARAM_FORCE_LOCATION, forceLocation) + ilLocation?.let { + appendQueryParameter(PARAM_FORCE_LOCATION, it.toString()) } if (vector.isNotBlank()) { appendQueryParameter(PARAM_VECTOR, vector) diff --git a/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/integrationlayer/service/IlLocation.kt b/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/integrationlayer/service/IlLocation.kt new file mode 100644 index 000000000..9223d9652 --- /dev/null +++ b/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/integrationlayer/service/IlLocation.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) SRG SSR. All rights reserved. + * License information is available from the LICENSE file. + */ +package ch.srgssr.pillarbox.core.business.integrationlayer.service + +/** + * Represents the location from which requests to the integration layer are made. + */ +enum class IlLocation { + /** + * Represents Switzerland. + */ + CH, + + /** + * Represents the rest of the world. + */ + WW; + + @Suppress("UndocumentedPublicClass") + companion object { + /** + * Retrieves an [IlLocation] associated with the given [name]. + * + * @param name The name to search for. + * @return The [IlLocation] associated with the name, or `null` if not found. + */ + fun fromName(name: String): IlLocation? { + return entries.find { it.name.equals(name, ignoreCase = true) } + } + } +} diff --git a/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/SRGMediaItemBuilderTest.kt b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/SRGMediaItemBuilderTest.kt index d85b72692..a47d07215 100644 --- a/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/SRGMediaItemBuilderTest.kt +++ b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/SRGMediaItemBuilderTest.kt @@ -10,6 +10,7 @@ import androidx.media3.common.MediaItem import androidx.media3.common.MediaMetadata import androidx.test.ext.junit.runners.AndroidJUnit4 import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlHost +import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlLocation import ch.srgssr.pillarbox.core.business.integrationlayer.service.Vector import ch.srgssr.pillarbox.core.business.source.MimeTypeSrg import org.junit.runner.RunWith @@ -195,18 +196,18 @@ class SRGMediaItemBuilderTest { } @Test - fun `Check set forceLocation`() { + fun `Check set ilLocation`() { val urn = "urn:rts:audio:3262363" val ilHost = IlHost.STAGE - val forceLocation = "CH" + val ilLocation = IlLocation.CH val mediaItem = SRGMediaItem(urn) { host(ilHost) - forceLocation(forceLocation) + ilLocation(ilLocation) } val localConfiguration = mediaItem.localConfiguration assertNotNull(localConfiguration) - assertEquals(urn.toIlUri(ilHost, forceLocation = forceLocation), localConfiguration.uri) + assertEquals(urn.toIlUri(ilHost, ilLocation = ilLocation), localConfiguration.uri) assertEquals(MimeTypeSrg, localConfiguration.mimeType) assertEquals(urn, mediaItem.mediaId) assertEquals(MediaMetadata.EMPTY, mediaItem.mediaMetadata) @@ -217,12 +218,12 @@ class SRGMediaItemBuilderTest { host: URL = IlHost.DEFAULT, vector: String = Vector.MOBILE, forceSAM: Boolean = false, - forceLocation: String? = null, + ilLocation: IlLocation? = null, ): Uri { val samPath = if (forceSAM) "sam/" else "" val queryParameters = listOfNotNull( if (forceSAM) "forceSAM" to true else null, - if (forceLocation != null) "forceLocation" to forceLocation else null, + if (ilLocation != null) "forceLocation" to ilLocation else null, if (vector.isNotBlank()) "vector" to vector else null, "onlyChapters" to true, ).joinToString(separator = "&") { (name, value) -> diff --git a/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/integrationlayer/service/IlLocationTest.kt b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/integrationlayer/service/IlLocationTest.kt new file mode 100644 index 000000000..d2226e887 --- /dev/null +++ b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/integrationlayer/service/IlLocationTest.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) SRG SSR. All rights reserved. + * License information is available from the LICENSE file. + */ +package ch.srgssr.pillarbox.core.business.integrationlayer.service + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull + +class IlLocationTest { + @Test + fun `fromName CH`() { + assertEquals(IlLocation.CH, IlLocation.fromName("ch")) + assertEquals(IlLocation.CH, IlLocation.fromName("CH")) + } + + @Test + fun `fromName WW`() { + assertEquals(IlLocation.WW, IlLocation.fromName("ww")) + assertEquals(IlLocation.WW, IlLocation.fromName("WW")) + } + + @Test + fun `fromName invalid name`() { + assertNull(IlLocation.fromName("INVALID")) + } +} diff --git a/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/DemoItem.kt b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/DemoItem.kt index b795d8930..e8bd0eaa8 100644 --- a/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/DemoItem.kt +++ b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/DemoItem.kt @@ -11,6 +11,7 @@ import androidx.media3.common.MediaItem.DrmConfiguration import androidx.media3.common.MediaMetadata import ch.srgssr.pillarbox.core.business.SRGMediaItem import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlHost +import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlLocation import java.io.Serializable /** @@ -75,7 +76,7 @@ sealed class DemoItem( * @property imageUri The optional image URI of the media. * @property host The host from which to load the media. * @property forceSAM Whether to use SAM instead of the IL. - * @property forceLocation The optional location from which to load the media (either `CH`, `WW`, or `null`). + * @property ilLocation The optional location from which to load the media. */ data class URN( val urn: String, @@ -84,13 +85,13 @@ sealed class DemoItem( override val imageUri: String? = null, val host: java.net.URL = IlHost.PROD, val forceSAM: Boolean = false, - val forceLocation: String? = null, + val ilLocation: IlLocation? = null, ) : DemoItem(urn, title, description, imageUri) { override fun toMediaItem(): MediaItem { return SRGMediaItem(urn) { host(host) forceSAM(forceSAM) - forceLocation(forceLocation) + ilLocation(ilLocation) mediaMetadata { setTitle(title) setDescription(description) diff --git a/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/di/PlayerModule.kt b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/di/PlayerModule.kt index ca7638de4..cf0db2a8e 100644 --- a/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/di/PlayerModule.kt +++ b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/di/PlayerModule.kt @@ -10,6 +10,7 @@ import ch.srg.dataProvider.integrationlayer.dependencies.modules.OkHttpModule import ch.srgssr.dataprovider.paging.DataProviderPaging import ch.srgssr.pillarbox.core.business.PillarboxExoPlayer import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlHost +import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlLocation import ch.srgssr.pillarbox.demo.shared.source.BlockedTimeRangeAssetLoader import ch.srgssr.pillarbox.demo.shared.source.CustomAssetLoader import ch.srgssr.pillarbox.demo.shared.ui.integrationLayer.data.ILRepository @@ -40,7 +41,7 @@ object PlayerModule { context: Context, ilHost: URL = IlHost.DEFAULT, forceSAM: Boolean = false, - ilLocation: String? = null, + ilLocation: IlLocation? = null, ): ILRepository { val okHttp = OkHttpModule.createOkHttpClient(context) .newBuilder() @@ -79,16 +80,16 @@ object PlayerModule { } } - private class LocationInterceptor(private val location: String?) : Interceptor { + private class LocationInterceptor(private val location: IlLocation?) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() - if (location.isNullOrBlank()) { + if (location == null) { return chain.proceed(request) } val newUrl = request.url .newBuilder() - .addQueryParameter("forceLocation", location) + .addQueryParameter("forceLocation", location.toString()) .build() val newRequest = request.newBuilder() .url(newUrl) diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/MainNavigation.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/MainNavigation.kt index e7ef1af05..4a7b62627 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/MainNavigation.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/MainNavigation.kt @@ -53,6 +53,7 @@ import ch.srg.dataProvider.integrationlayer.request.image.ImageWidth import ch.srg.dataProvider.integrationlayer.request.image.decorated import ch.srgssr.pillarbox.analytics.SRGAnalytics import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlHost +import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlLocation import ch.srgssr.pillarbox.demo.shared.data.DemoItem import ch.srgssr.pillarbox.demo.shared.di.PlayerModule import ch.srgssr.pillarbox.demo.shared.ui.HomeDestination @@ -94,7 +95,7 @@ fun MainNavigation() { var ilHost by remember { mutableStateOf(IlHost.DEFAULT) } var forceSAM by remember { mutableStateOf(false) } - var ilLocation by remember { mutableStateOf(null) } + var ilLocation by remember { mutableStateOf(null) } Scaffold( topBar = { @@ -187,8 +188,8 @@ fun MainNavigation() { private fun ListsMenu( currentServer: URL, currentForceSAM: Boolean, - currentLocation: String?, - onServerSelected: (server: URL, forceSAM: Boolean, location: String?) -> Unit + currentLocation: IlLocation?, + onServerSelected: (server: URL, forceSAM: Boolean, location: IlLocation?) -> Unit ) { var isMenuVisible by remember { mutableStateOf(false) } @@ -247,7 +248,7 @@ private fun ListsMenu( } internal fun getServers(context: Context): List { - val ilServers = listOf(null, "CH", "WW").flatMap { location -> + val ilServers = listOf(null, IlLocation.CH, IlLocation.WW).flatMap { location -> val name = location?.let { "IL ($location)" } ?: "IL" listOf( @@ -300,7 +301,7 @@ internal data class EnvironmentConfig( val serverName: String, val host: URL, val forceSAM: Boolean = false, - val location: String? = null, + val location: IlLocation? = null, ) { val displayName: String get() = "$serverName - $name" diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/examples/InsertContentView.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/examples/InsertContentView.kt index 340481e3e..2cbbab84b 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/examples/InsertContentView.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/examples/InsertContentView.kt @@ -86,7 +86,7 @@ private data class InsertContentData( urn = uri, host = checkNotNull(environmentConfig).host, forceSAM = environmentConfig.forceSAM, - forceLocation = environmentConfig.location, + ilLocation = environmentConfig.location, ) else -> DemoItem.URL( diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/lists/ListsHome.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/lists/ListsHome.kt index c02ef5834..308f78258 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/lists/ListsHome.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/lists/ListsHome.kt @@ -20,6 +20,7 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.toRoute import androidx.paging.compose.collectAsLazyPagingItems +import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlLocation import ch.srgssr.pillarbox.demo.DemoPageView import ch.srgssr.pillarbox.demo.composable import ch.srgssr.pillarbox.demo.shared.data.DemoItem @@ -47,7 +48,7 @@ fun NavGraphBuilder.listsNavGraph( ilRepository: ILRepository, ilHost: URL, forceSAM: Boolean, - ilLocation: String?, + ilLocation: IlLocation?, ) { val contentClick = { contentList: ContentList, content: Content -> when (content) { @@ -75,7 +76,7 @@ fun NavGraphBuilder.listsNavGraph( urn = content.urn, host = ilHost, forceSAM = forceSAM, - forceLocation = ilLocation, + ilLocation = ilLocation, ) SimplePlayerActivity.startActivity(navController.context, item)