diff --git a/build.gradle.kts b/build.gradle.kts
index 4b37ac619..7c0e4a1a6 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -4,6 +4,7 @@
*/
import io.gitlab.arturbosch.detekt.Detekt
// Top-level build file where you can add configuration options common to all sub-projects/modules.
+@Suppress("DSL_SCOPE_VIOLATION") // TODO Remove once KTIJ-19369 is fixed
plugins {
// known bug for libs : https://developer.android.com/studio/preview/features#gradle-version-catalogs-known-issues
alias(libs.plugins.android.application) apply false
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 0e96f8f41..9a650a341 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -29,6 +29,11 @@ tagCommanderServerSide = "5.5.0"
# ComScore : https://github.com/comScore/ComScore-Android
comscore = "6.10.0"
androidxComposeBom = "2023.08.00"
+leanback = "1.0.0"
+tvCompose = "1.0.0-alpha09"
+androidx-test-ext-junit = "1.1.5"
+appcompat = "1.6.1"
+material = "1.9.0"
[libraries]
accompanist-navigation-material = { module = "com.google.accompanist:accompanist-navigation-material", version.ref = "accompanist" }
@@ -37,6 +42,8 @@ androidx-activity-compose = { module = "androidx.activity:activity-compose", ver
androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycleViewmodelCompose" }
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
androidx-paging-compose = { module = "androidx.paging:paging-compose", version.ref = "pagingCompose" }
+androidx-tv-foundation = { module = "androidx.tv:tv-foundation", version.ref = "tvCompose" }
+androidx-tv-material = { module = "androidx.tv:tv-material", version.ref = "tvCompose" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktorVersion" }
ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktorVersion" }
@@ -61,6 +68,7 @@ kotlinx-coroutines-guava = { group = "org.jetbrains.kotlinx", name = "kotlinx-co
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutines" }
androidx-media3-exoplayer = { group = "androidx.media3", name = "media3-exoplayer", version.ref = "media3" }
androidx-media3-ui = { group = "androidx.media3", name = "media3-ui", version.ref = "media3" }
+androidx-media3-ui-leanback = { group = "androidx.media3", name = "media3-ui-leanback", version.ref = "media3" }
androidx-media3-dash = { group = "androidx.media3", name = "media3-exoplayer-dash", version.ref = "media3" }
androidx-media3-hls = { group = "androidx.media3", name = "media3-exoplayer-hls", version.ref = "media3" }
androidx-media3-session = { group = "androidx.media3", name = "media3-session", version.ref = "media3" }
@@ -80,6 +88,10 @@ androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "u
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" }
+leanback = { group = "androidx.leanback", name = "leanback", version.ref = "leanback" }
+androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" }
+appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
diff --git a/pillarbox-analytics/build.gradle.kts b/pillarbox-analytics/build.gradle.kts
index d9c078a73..0c854402e 100644
--- a/pillarbox-analytics/build.gradle.kts
+++ b/pillarbox-analytics/build.gradle.kts
@@ -2,6 +2,7 @@
* Copyright (c) 2022. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
+@Suppress("DSL_SCOPE_VIOLATION") // TODO Remove once KTIJ-19369 is fixed
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
diff --git a/pillarbox-core-business/build.gradle.kts b/pillarbox-core-business/build.gradle.kts
index 593b5dea0..1baed4f74 100644
--- a/pillarbox-core-business/build.gradle.kts
+++ b/pillarbox-core-business/build.gradle.kts
@@ -2,6 +2,7 @@
* Copyright (c) 2022. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
+@Suppress("DSL_SCOPE_VIOLATION") // TODO Remove once KTIJ-19369 is fixed
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
diff --git a/pillarbox-demo-shared/.gitignore b/pillarbox-demo-shared/.gitignore
new file mode 100644
index 000000000..42afabfd2
--- /dev/null
+++ b/pillarbox-demo-shared/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/pillarbox-demo-shared/build.gradle.kts b/pillarbox-demo-shared/build.gradle.kts
new file mode 100644
index 000000000..1a781ce1f
--- /dev/null
+++ b/pillarbox-demo-shared/build.gradle.kts
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
+ * License information is available from the LICENSE file.
+ */
+@Suppress("DSL_SCOPE_VIOLATION") // TODO Remove once KTIJ-19369 is fixed
+plugins {
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "ch.srgssr.pillarbox.demo.shared"
+ compileSdk = AppConfig.compileSdk
+
+ defaultConfig {
+ minSdk = AppConfig.minSdk
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles("consumer-rules.pro")
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+dependencies {
+ compileOnly(project(mapOf("path" to ":pillarbox-core-business")))
+ implementation(libs.androidx.ktx)
+}
diff --git a/pillarbox-demo-shared/consumer-rules.pro b/pillarbox-demo-shared/consumer-rules.pro
new file mode 100644
index 000000000..e69de29bb
diff --git a/pillarbox-demo-shared/proguard-rules.pro b/pillarbox-demo-shared/proguard-rules.pro
new file mode 100644
index 000000000..481bb4348
--- /dev/null
+++ b/pillarbox-demo-shared/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/pillarbox-demo-shared/src/main/AndroidManifest.xml b/pillarbox-demo-shared/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..09709e5c1
--- /dev/null
+++ b/pillarbox-demo-shared/src/main/AndroidManifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/data/DemoBrowser.kt b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/DemoBrowser.kt
similarity index 96%
rename from pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/data/DemoBrowser.kt
rename to pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/DemoBrowser.kt
index 1bade0629..d29957fe7 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/data/DemoBrowser.kt
+++ b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/DemoBrowser.kt
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2022. SRG SSR. All rights reserved.
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
-package ch.srgssr.pillarbox.demo.data
+package ch.srgssr.pillarbox.demo.shared.data
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/data/DemoItem.kt b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/DemoItem.kt
similarity index 99%
rename from pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/data/DemoItem.kt
rename to pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/DemoItem.kt
index eefe86d95..0bf3ac259 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/data/DemoItem.kt
+++ b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/DemoItem.kt
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2022. SRG SSR. All rights reserved.
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
@file:Suppress("MaximumLineLength", "MaxLineLength")
-package ch.srgssr.pillarbox.demo.data
+package ch.srgssr.pillarbox.demo.shared.data
import android.net.Uri
import androidx.media3.common.C
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/data/MixedMediaItemSource.kt b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/MixedMediaItemSource.kt
similarity index 91%
rename from pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/data/MixedMediaItemSource.kt
rename to pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/MixedMediaItemSource.kt
index c404c9d17..aaf3d9dc8 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/data/MixedMediaItemSource.kt
+++ b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/MixedMediaItemSource.kt
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2022. SRG SSR. All rights reserved.
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
-package ch.srgssr.pillarbox.demo.data
+package ch.srgssr.pillarbox.demo.shared.data
import androidx.media3.common.MediaItem
import ch.srgssr.pillarbox.core.business.MediaCompositionMediaItemSource
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/data/Playlist.kt b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/Playlist.kt
similarity index 99%
rename from pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/data/Playlist.kt
rename to pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/Playlist.kt
index 60bdfc8d2..a7a3c2019 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/data/Playlist.kt
+++ b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/data/Playlist.kt
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2022. SRG SSR. All rights reserved.
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
-package ch.srgssr.pillarbox.demo.data
+package ch.srgssr.pillarbox.demo.shared.data
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/di/PlayerModule.kt b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/di/PlayerModule.kt
similarity index 94%
rename from pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/di/PlayerModule.kt
rename to pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/di/PlayerModule.kt
index da0d68b0f..1a7794665 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/di/PlayerModule.kt
+++ b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/di/PlayerModule.kt
@@ -2,7 +2,7 @@
* Copyright (c) 2023. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
-package ch.srgssr.pillarbox.demo.di
+package ch.srgssr.pillarbox.demo.shared.di
import android.content.Context
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
@@ -12,7 +12,7 @@ import ch.srgssr.pillarbox.core.business.akamai.AkamaiTokenDataSource
import ch.srgssr.pillarbox.core.business.integrationlayer.service.DefaultMediaCompositionDataSource
import ch.srgssr.pillarbox.core.business.integrationlayer.service.Vector.getVector
import ch.srgssr.pillarbox.core.business.tracker.DefaultMediaItemTrackerRepository
-import ch.srgssr.pillarbox.demo.data.MixedMediaItemSource
+import ch.srgssr.pillarbox.demo.shared.data.MixedMediaItemSource
import ch.srgssr.pillarbox.player.PillarboxPlayer
import ch.srgssr.pillarbox.player.source.PillarboxMediaSourceFactory
diff --git a/pillarbox-demo-tv/.gitignore b/pillarbox-demo-tv/.gitignore
new file mode 100644
index 000000000..42afabfd2
--- /dev/null
+++ b/pillarbox-demo-tv/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/pillarbox-demo-tv/build.gradle.kts b/pillarbox-demo-tv/build.gradle.kts
new file mode 100644
index 000000000..fe0bbad6b
--- /dev/null
+++ b/pillarbox-demo-tv/build.gradle.kts
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
+ * License information is available from the LICENSE file.
+ */
+@Suppress("DSL_SCOPE_VIOLATION") // TODO Remove once KTIJ-19369 is fixed
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "ch.srgssr.pillarbox.demo.tv"
+ compileSdk = AppConfig.compileSdk
+
+ defaultConfig {
+ applicationId = "ch.srgssr.pillarbox.demo.tv"
+ minSdk = AppConfig.minSdk
+ targetSdk = AppConfig.targetSdk
+ versionCode = VersionConfig.versionCode()
+ versionName = VersionConfig.versionName()
+ }
+
+ signingConfigs {
+ create("release") {
+ val password = System.getenv("DEMO_KEY_PASSWORD") ?: extra.properties["pillarbox.keystore.password"] as String?
+ storeFile = file("./demo.keystore")
+ storePassword = password
+ keyAlias = "demo"
+ keyPassword = password
+ }
+ }
+
+ buildTypes {
+ debug {
+ applicationIdSuffix = ".debug"
+ versionNameSuffix = "-debug"
+ }
+ release {
+ isMinifyEnabled = false
+ proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+ kotlinOptions {
+ jvmTarget = "17"
+ }
+ buildFeatures {
+ compose = true
+ }
+
+ composeOptions {
+ kotlinCompilerExtensionVersion = AppConfig.composeCompiler
+ }
+}
+
+dependencies {
+ implementation(project(mapOf("path" to ":pillarbox-core-business")))
+ implementation(project(mapOf("path" to ":pillarbox-analytics")))
+ implementation(project(mapOf("path" to ":pillarbox-ui")))
+ implementation(project(mapOf("path" to ":pillarbox-demo-shared")))
+ implementation(libs.androidx.ktx)
+ implementation(libs.leanback)
+
+ val composeBom = libs.androidx.compose.bom
+ implementation(platform(composeBom))
+ implementation(libs.androidx.activity.compose)
+ implementation(libs.androidx.compose.material.icons.extended)
+ implementation(libs.androidx.compose.ui)
+ implementation(libs.androidx.compose.ui.tooling.preview)
+
+ // Compose for TV dependencies
+ implementation(libs.androidx.tv.foundation)
+ implementation(libs.androidx.tv.material)
+ implementation(libs.androidx.media3.ui.leanback)
+}
diff --git a/pillarbox-demo-tv/proguard-rules.pro b/pillarbox-demo-tv/proguard-rules.pro
new file mode 100644
index 000000000..481bb4348
--- /dev/null
+++ b/pillarbox-demo-tv/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/pillarbox-demo-tv/src/main/AndroidManifest.xml b/pillarbox-demo-tv/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..bd6184d16
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/AndroidManifest.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/DemoTvApplication.kt b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/DemoTvApplication.kt
new file mode 100644
index 000000000..cb5489b96
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/DemoTvApplication.kt
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
+ * License information is available from the LICENSE file.
+ */
+package ch.srgssr.pillarbox.demo.tv
+
+import android.app.Application
+
+/**
+ * Demo tv application
+ *
+ * @constructor Create empty Demo tv application
+ */
+class DemoTvApplication : Application()
diff --git a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/MainActivity.kt b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/MainActivity.kt
new file mode 100644
index 000000000..81ad7af41
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/MainActivity.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
+ * License information is available from the LICENSE file.
+ */
+@file:OptIn(ExperimentalTvMaterial3Api::class)
+
+package ch.srgssr.pillarbox.demo.tv
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.unit.dp
+import androidx.tv.material3.Border
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.MaterialTheme
+import androidx.tv.material3.Surface
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.tv.examples.ExamplesHome
+import ch.srgssr.pillarbox.demo.tv.player.PlayerActivity
+
+/**
+ * Main activity
+ *
+ * @constructor Create empty Main activity
+ */
+class MainActivity : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ MaterialTheme {
+ Surface(
+ shape = RectangleShape,
+ border = Border.None
+ ) {
+ MainView(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(
+ start = HorizontalPadding,
+ end = HorizontalPadding,
+ top = VerticalPadding,
+ ),
+ this@MainActivity::openPlayer
+ )
+ }
+ }
+ }
+ }
+
+ private fun openPlayer(item: DemoItem) {
+ PlayerActivity.startPlayer(this, item)
+ }
+
+ @Composable
+ private fun MainView(
+ modifier: Modifier = Modifier,
+ onItemSelected: (DemoItem) -> Unit
+ ) {
+ ExamplesHome(modifier = modifier, onItemSelected = onItemSelected)
+ }
+
+ companion object {
+ private val HorizontalPadding = 32.dp
+ private val VerticalPadding = 16.dp
+ }
+}
diff --git a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/examples/Examples.kt b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/examples/Examples.kt
new file mode 100644
index 000000000..12d7376f4
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/examples/Examples.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
+ * License information is available from the LICENSE file.
+ */
+package ch.srgssr.pillarbox.demo.tv.examples
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.tv.foundation.ExperimentalTvFoundationApi
+import androidx.tv.foundation.PivotOffsets
+import androidx.tv.foundation.lazy.list.TvLazyColumn
+import androidx.tv.foundation.lazy.list.items
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.MaterialTheme
+import androidx.tv.material3.Surface
+import androidx.tv.material3.Text
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.data.Playlist
+import ch.srgssr.pillarbox.demo.tv.item.DemoItemView
+import ch.srgssr.pillarbox.demo.tv.item.PlaylistHeader
+
+/**
+ * Examples home
+ *
+ * @param modifier
+ * @param onItemSelected
+ * @receiver
+ */
+@OptIn(ExperimentalTvFoundationApi::class, ExperimentalTvMaterial3Api::class)
+@Composable
+fun ExamplesHome(
+ modifier: Modifier = Modifier,
+ onItemSelected: (DemoItem) -> Unit = {},
+) {
+ val listItems = remember {
+ listOf(
+ Playlist.StreamUrls,
+ Playlist.StreamUrns,
+ Playlist.PlaySuisseStreams,
+ Playlist.StreamApples,
+ Playlist.StreamGoogles,
+ Playlist.BitmovinSamples,
+ Playlist.UnifiedStreaming,
+ Playlist.UnifiedStreamingDash,
+ )
+ }
+ TvLazyColumn(
+ modifier = modifier,
+ pivotOffsets = PivotOffsets(0.5f, 0f),
+ verticalArrangement = Arrangement.spacedBy(16.dp)
+ ) {
+ stickyHeader {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(bottom = 12.dp)
+ .background(color = MaterialTheme.colorScheme.surface)
+ ) {
+ Text(text = "Samples", style = MaterialTheme.typography.displayMedium)
+ }
+ }
+ for (playlist in listItems) {
+ item {
+ PlaylistHeader(
+ modifier = Modifier.padding(vertical = 6.dp),
+ title = playlist.title
+ )
+ }
+ items(playlist.items) { item ->
+ DemoItemView(
+ modifier = Modifier.fillMaxWidth(),
+ title = item.title,
+ subtitle = item.description,
+ onClick = { onItemSelected(item) }
+ )
+ }
+ }
+ }
+}
+
+@OptIn(ExperimentalTvMaterial3Api::class)
+@Preview
+@Composable
+private fun ExamplesPreview() {
+ MaterialTheme() {
+ Surface {
+ ExamplesHome()
+ }
+ }
+}
diff --git a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/item/DemoItemView.kt b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/item/DemoItemView.kt
new file mode 100644
index 000000000..6e0a8e1e4
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/item/DemoItemView.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
+ * License information is available from the LICENSE file.
+ */
+package ch.srgssr.pillarbox.demo.tv.item
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.tv.material3.Card
+import androidx.tv.material3.CardScale
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.MaterialTheme
+import androidx.tv.material3.Text
+
+/**
+ * Demo item view
+ *
+ * @param title
+ * @param onClick
+ * @param modifier
+ * @param subtitle
+ * @receiver
+ */
+@OptIn(ExperimentalTvMaterial3Api::class)
+@Composable
+fun DemoItemView(
+ title: String,
+ onClick: () -> Unit,
+ modifier: Modifier = Modifier,
+ subtitle: String? = null
+) {
+ Card(
+ modifier = modifier,
+ onClick = onClick,
+ scale = CardScale.None
+ ) {
+ Column(
+ modifier = Modifier.padding(8.dp),
+ verticalArrangement = Arrangement.spacedBy(2.dp)
+ ) {
+ Text(
+ modifier = Modifier,
+ text = title,
+ maxLines = 2,
+ overflow = TextOverflow.Ellipsis,
+ style = MaterialTheme.typography.titleLarge,
+ )
+ subtitle?.let {
+ Text(
+ modifier = Modifier,
+ text = subtitle,
+ maxLines = 2,
+ overflow = TextOverflow.Ellipsis,
+ style = MaterialTheme.typography.bodyLarge,
+ )
+ }
+ }
+ }
+}
+
+@OptIn(ExperimentalTvMaterial3Api::class)
+@Preview
+@Composable
+private fun DemoItemPreview() {
+ MaterialTheme {
+ Column(
+ modifier = Modifier
+ .width(400.dp),
+ verticalArrangement = Arrangement.spacedBy(8.dp)
+ ) {
+ val itemModifier = Modifier
+ .fillMaxWidth()
+ DemoItemView(modifier = itemModifier, title = "Title 1", subtitle = "Subtitle 1", onClick = { })
+ DemoItemView(modifier = itemModifier, title = "Title 2", subtitle = null, onClick = {})
+ DemoItemView(modifier = itemModifier, title = "Title 3", subtitle = "Subtitle 3", onClick = { })
+ }
+ }
+}
diff --git a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/item/PlaylistHeader.kt b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/item/PlaylistHeader.kt
new file mode 100644
index 000000000..d6dc24701
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/item/PlaylistHeader.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
+ * License information is available from the LICENSE file.
+ */
+package ch.srgssr.pillarbox.demo.tv.item
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.MaterialTheme
+import androidx.tv.material3.Text
+
+/**
+ * Playlist header
+ *
+ * @param title The title of the playlist.
+ * @param modifier
+ */
+@OptIn(ExperimentalTvMaterial3Api::class)
+@Composable
+fun PlaylistHeader(title: String, modifier: Modifier = Modifier) {
+ Text(
+ modifier = modifier,
+ text = title,
+ style = MaterialTheme.typography.headlineSmall,
+ )
+}
diff --git a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/PlayerActivity.kt b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/PlayerActivity.kt
new file mode 100644
index 000000000..a0f50d762
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/PlayerActivity.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
+ * License information is available from the LICENSE file.
+ */
+package ch.srgssr.pillarbox.demo.tv.player
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import androidx.media3.session.MediaSession
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.MaterialTheme
+import androidx.tv.material3.Surface
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.di.PlayerModule
+import ch.srgssr.pillarbox.demo.tv.player.compose.TvPlayerView
+import ch.srgssr.pillarbox.player.PillarboxPlayer
+
+/**
+ * Player activity
+ *
+ * @constructor Create empty Player activity
+ */
+class PlayerActivity : ComponentActivity() {
+ private lateinit var player: PillarboxPlayer
+ private lateinit var mediaSession: MediaSession
+
+ @OptIn(ExperimentalTvMaterial3Api::class)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ player = PlayerModule.provideDefaultPlayer(this)
+ mediaSession = MediaSession.Builder(this, player)
+ .build()
+ val demoItem = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ intent.getSerializableExtra(ARG_ITEM, DemoItem::class.java)
+ } else {
+ intent.getSerializableExtra(ARG_ITEM) as DemoItem?
+ }
+ demoItem?.let {
+ player.setMediaItem(it.toMediaItem())
+ }
+ player.apply {
+ player.prepare()
+ player.trackingEnabled = false
+ player.playWhenReady = true
+ }
+
+ setContent {
+ MaterialTheme {
+ Surface(modifier = Modifier.fillMaxSize()) {
+ TvPlayerView(player = player)
+ }
+ }
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ player.play()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ player.pause()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ mediaSession.release()
+ player.stop()
+ player.release()
+ }
+
+ companion object {
+ private const val ARG_ITEM = "demo_item"
+
+ /**
+ * Start player with Leanback fragment.
+ *
+ * @param context
+ * @param demoItem The item to play.
+ */
+ fun startPlayer(context: Activity, demoItem: DemoItem) {
+ val intent = Intent(context, PlayerActivity::class.java)
+ intent.putExtra(ARG_ITEM, demoItem)
+ context.startActivity(intent)
+ }
+ }
+}
diff --git a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/compose/TvPlaybackRow.kt b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/compose/TvPlaybackRow.kt
new file mode 100644
index 000000000..593d3eb98
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/compose/TvPlaybackRow.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
+ * License information is available from the LICENSE file.
+ */
+package ch.srgssr.pillarbox.demo.tv.player.compose
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.FastForward
+import androidx.compose.material.icons.filled.FastRewind
+import androidx.compose.material.icons.filled.Pause
+import androidx.compose.material.icons.filled.PlayArrow
+import androidx.compose.material.icons.filled.SkipNext
+import androidx.compose.material.icons.filled.SkipPrevious
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.unit.dp
+import androidx.media3.common.Player
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.Icon
+import androidx.tv.material3.IconButton
+import ch.srgssr.pillarbox.player.canSeekBack
+import ch.srgssr.pillarbox.player.canSeekForward
+import ch.srgssr.pillarbox.player.canSeekToNext
+import ch.srgssr.pillarbox.player.canSeekToPrevious
+import ch.srgssr.pillarbox.ui.availableCommandsAsState
+import ch.srgssr.pillarbox.ui.isPlayingAsState
+
+/**
+ * Tv playback row
+ *
+ * @param player
+ * @param modifier
+ */
+@OptIn(ExperimentalTvMaterial3Api::class)
+@Composable
+fun TvPlaybackRow(
+ player: Player,
+ modifier: Modifier = Modifier,
+) {
+ val isPlaying = player.isPlayingAsState()
+ val focusRequester = remember {
+ FocusRequester()
+ }
+ LaunchedEffect(Unit) {
+ focusRequester.requestFocus()
+ }
+ Row(
+ modifier = modifier,
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ ) {
+ IconButton(
+ modifier = Modifier,
+ enabled = player.availableCommandsAsState().canSeekToPrevious(),
+ onClick = {
+ player.seekToPrevious()
+ },
+ ) {
+ Icon(imageVector = Icons.Default.SkipPrevious, contentDescription = null)
+ }
+
+ IconButton(
+ modifier = Modifier,
+ enabled = player.availableCommandsAsState().canSeekBack(),
+ onClick = {
+ player.seekBack()
+ },
+ ) {
+ Icon(imageVector = Icons.Default.FastRewind, contentDescription = null)
+ }
+
+ IconButton(
+ modifier = Modifier
+ .focusRequester(focusRequester),
+ onClick = {
+ player.playWhenReady = !player.playWhenReady
+ },
+ ) {
+ if (isPlaying) {
+ Icon(imageVector = Icons.Default.Pause, contentDescription = null)
+ } else {
+ Icon(imageVector = Icons.Default.PlayArrow, contentDescription = null)
+ }
+ }
+
+ IconButton(
+ modifier = Modifier,
+ enabled = player.availableCommandsAsState().canSeekForward(),
+ onClick = {
+ player.seekForward()
+ },
+ ) {
+ Icon(imageVector = Icons.Default.FastForward, contentDescription = null)
+ }
+
+ IconButton(
+ modifier = Modifier,
+ enabled = player.availableCommandsAsState().canSeekToNext(),
+ onClick = {
+ player.seekToNext()
+ },
+ ) {
+ Icon(imageVector = Icons.Default.SkipNext, contentDescription = null)
+ }
+ }
+}
diff --git a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/compose/TvPlayerView.kt b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/compose/TvPlayerView.kt
new file mode 100644
index 000000000..8c9f3cc3b
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/compose/TvPlayerView.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
+ * License information is available from the LICENSE file.
+ */
+package ch.srgssr.pillarbox.demo.tv.player.compose
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.media3.common.Player
+import ch.srgssr.pillarbox.ui.PlayerSurface
+import ch.srgssr.pillarbox.ui.ToggleView
+import ch.srgssr.pillarbox.ui.rememberToggleState
+import kotlin.time.Duration.Companion.seconds
+
+/**
+ * Tv player view
+ *
+ * @param player
+ * @param modifier
+ */
+@Composable
+fun TvPlayerView(
+ player: Player,
+ modifier: Modifier = Modifier
+) {
+ Box(modifier = modifier) {
+ PlayerSurface(
+ player = player,
+ modifier = Modifier.fillMaxSize()
+ ) {
+ val toggleState = rememberToggleState(visible = true, duration = 4.seconds)
+ Box(
+ contentAlignment = Alignment.Center,
+ modifier = Modifier
+ .fillMaxSize()
+ .clickable {
+ toggleState.toggleVisible()
+ }
+ ) {
+ ToggleView(toggleState = toggleState) {
+ TvPlaybackRow(
+ player = player,
+ modifier = Modifier.matchParentSize()
+ )
+ }
+ }
+ }
+ }
+}
diff --git a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/leanback/LeanbackPlayerActivity.kt b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/leanback/LeanbackPlayerActivity.kt
new file mode 100644
index 000000000..0fe368683
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/leanback/LeanbackPlayerActivity.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
+ * License information is available from the LICENSE file.
+ */
+package ch.srgssr.pillarbox.demo.tv.player.leanback
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import androidx.fragment.app.FragmentActivity
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.tv.R
+
+/**
+ * Player activity using Android Leanback.
+ *
+ * Leanback is no more update by google and very complicated to implement.
+ * This demo just show how to integrate Leanback with Pillarbox.
+ */
+class LeanbackPlayerActivity : FragmentActivity() {
+
+ private lateinit var leanbackPlayerFragment: LeanbackPlayerFragment
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_player)
+ leanbackPlayerFragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as LeanbackPlayerFragment
+ val demoItem = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ intent.getSerializableExtra(ARG_ITEM, DemoItem::class.java)
+ } else {
+ intent.getSerializableExtra(ARG_ITEM) as DemoItem?
+ }
+ demoItem?.let {
+ leanbackPlayerFragment.setDemoItem(it)
+ }
+ }
+
+ companion object {
+ private const val ARG_ITEM = "demo_item"
+
+ /**
+ * Start player with Leanback fragment.
+ *
+ * @param context
+ * @param demoItem The item to play.
+ */
+ fun startPlayer(context: Activity, demoItem: DemoItem) {
+ val intent = Intent(context, LeanbackPlayerActivity::class.java)
+ intent.putExtra(ARG_ITEM, demoItem)
+ context.startActivity(intent)
+ }
+ }
+}
diff --git a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/leanback/LeanbackPlayerFragment.kt b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/leanback/LeanbackPlayerFragment.kt
new file mode 100644
index 000000000..e019418db
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/player/leanback/LeanbackPlayerFragment.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2023. SRG SSR. All rights reserved.
+ * License information is available from the LICENSE file.
+ */
+package ch.srgssr.pillarbox.demo.tv.player.leanback
+
+import android.os.Bundle
+import android.util.Log
+import androidx.leanback.app.VideoSupportFragment
+import androidx.leanback.app.VideoSupportFragmentGlueHost
+import androidx.leanback.media.PlaybackGlue
+import androidx.leanback.media.PlaybackTransportControlGlue
+import androidx.leanback.widget.PlaybackSeekDataProvider
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.flowWithLifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.media3.common.Player
+import androidx.media3.ui.leanback.LeanbackPlayerAdapter
+import ch.srgssr.pillarbox.core.business.SRGErrorMessageProvider
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.di.PlayerModule
+import ch.srgssr.pillarbox.player.PillarboxPlayer
+import ch.srgssr.pillarbox.player.currentMediaMetadataAsFlow
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.launch
+
+private const val UpdateInterval = 1_000
+
+/**
+ * Leanback player fragment
+ *
+ * A simple leanback player sample.
+ * Lot of work is still needed to have a good player experience.
+ */
+class LeanbackPlayerFragment : VideoSupportFragment() {
+ private lateinit var player: PillarboxPlayer
+
+ /**
+ * Set demo item to [PillarboxPlayer]
+ *
+ * @param demoItem
+ */
+ fun setDemoItem(demoItem: DemoItem) {
+ player.setMediaItem(demoItem.toMediaItem())
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ player = PlayerModule.provideDefaultPlayer(requireContext()).apply {
+ prepare()
+ setHandleAudioFocus(true)
+ }
+ val playerGlue = PlaybackTransportControlGlue(
+ requireActivity(),
+ LeanbackPlayerAdapter(
+ requireActivity(),
+ player,
+ UpdateInterval
+ ).apply {
+ setErrorMessageProvider(SRGErrorMessageProvider(requireContext()))
+ }
+ )
+ playerGlue.host = VideoSupportFragmentGlueHost(this)
+ playerGlue.addPlayerCallback(object : PlaybackGlue.PlayerCallback() {
+ override fun onPreparedStateChanged(glue: PlaybackGlue) {
+ if (glue.isPrepared) {
+ playerGlue.seekProvider = PlaybackSeekDataProvider()
+ playerGlue.play()
+ }
+ }
+ })
+ lifecycleScope.launch {
+ lifecycle.repeatOnLifecycle(Lifecycle.State.CREATED) {
+ player.currentMediaMetadataAsFlow().flowWithLifecycle(lifecycle).collectLatest {
+ playerGlue.subtitle = it.title
+ playerGlue.title = it.subtitle
+ }
+ }
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ if (player.playerError == null || player.playbackState == Player.STATE_ENDED) {
+ player.seekToDefaultPosition()
+ player.prepare()
+ }
+ player.play()
+ }
+
+ override fun onPause() {
+ Log.d("Coucou", "PlayerFragment:onPause")
+ super.onPause()
+ player.pause()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ Log.d("Coucou", "PlayerFragment:onDestroy")
+ player.release()
+ }
+}
diff --git a/pillarbox-demo-tv/src/main/res/layout/activity_player.xml b/pillarbox-demo-tv/src/main/res/layout/activity_player.xml
new file mode 100644
index 000000000..19106601e
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/res/layout/activity_player.xml
@@ -0,0 +1,9 @@
+
+
diff --git a/pillarbox-demo-tv/src/main/res/mipmap-hdpi/ic_launcher.webp b/pillarbox-demo-tv/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 000000000..c209e78ec
Binary files /dev/null and b/pillarbox-demo-tv/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/pillarbox-demo-tv/src/main/res/mipmap-mdpi/ic_launcher.webp b/pillarbox-demo-tv/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 000000000..4f0f1d64e
Binary files /dev/null and b/pillarbox-demo-tv/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/pillarbox-demo-tv/src/main/res/mipmap-xhdpi/ic_launcher.webp b/pillarbox-demo-tv/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 000000000..948a3070f
Binary files /dev/null and b/pillarbox-demo-tv/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/pillarbox-demo-tv/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/pillarbox-demo-tv/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 000000000..28d4b77f9
Binary files /dev/null and b/pillarbox-demo-tv/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/pillarbox-demo-tv/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/pillarbox-demo-tv/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 000000000..aa7d6427e
Binary files /dev/null and b/pillarbox-demo-tv/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/pillarbox-demo-tv/src/main/res/values/strings.xml b/pillarbox-demo-tv/src/main/res/values/strings.xml
new file mode 100644
index 000000000..c742e1224
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Pillarbox Demo Tv
+
\ No newline at end of file
diff --git a/pillarbox-demo-tv/src/main/res/values/themes.xml b/pillarbox-demo-tv/src/main/res/values/themes.xml
new file mode 100644
index 000000000..ee4d5bbf7
--- /dev/null
+++ b/pillarbox-demo-tv/src/main/res/values/themes.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/pillarbox-demo/build.gradle.kts b/pillarbox-demo/build.gradle.kts
index 4d2340a96..eaf5f085d 100644
--- a/pillarbox-demo/build.gradle.kts
+++ b/pillarbox-demo/build.gradle.kts
@@ -2,6 +2,7 @@
* Copyright (c) 2022. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
+@Suppress("DSL_SCOPE_VIOLATION") // TODO Remove once KTIJ-19369 is fixed
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
@@ -100,6 +101,7 @@ dependencies {
implementation(project(mapOf("path" to ":pillarbox-core-business")))
implementation(project(mapOf("path" to ":pillarbox-analytics")))
implementation(project(mapOf("path" to ":pillarbox-ui")))
+ implementation(project(mapOf("path" to ":pillarbox-demo-shared")))
implementation(libs.androidx.ktx)
val composeBom = libs.androidx.compose.bom
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/service/DemoMediaLibraryService.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/service/DemoMediaLibraryService.kt
index a2e1b04b1..a59205285 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/service/DemoMediaLibraryService.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/service/DemoMediaLibraryService.kt
@@ -11,8 +11,8 @@ import android.util.Log
import androidx.media3.common.MediaItem
import androidx.media3.session.LibraryResult
import androidx.media3.session.MediaSession
-import ch.srgssr.pillarbox.demo.data.DemoBrowser
-import ch.srgssr.pillarbox.demo.di.PlayerModule
+import ch.srgssr.pillarbox.demo.shared.data.DemoBrowser
+import ch.srgssr.pillarbox.demo.shared.di.PlayerModule
import ch.srgssr.pillarbox.demo.ui.player.mediacontroller.MediaControllerActivity
import ch.srgssr.pillarbox.player.service.PillarboxMediaLibraryService
import ch.srgssr.pillarbox.player.utils.PendingIntentUtils
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/service/DemoMediaSessionService.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/service/DemoMediaSessionService.kt
index 9d6509683..db8f08ab4 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/service/DemoMediaSessionService.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/service/DemoMediaSessionService.kt
@@ -9,8 +9,8 @@ import android.content.Intent
import android.util.Log
import androidx.media3.common.C
import androidx.media3.common.MediaItem
-import ch.srgssr.pillarbox.demo.data.DemoItem
-import ch.srgssr.pillarbox.demo.di.PlayerModule
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.di.PlayerModule
import ch.srgssr.pillarbox.demo.ui.player.mediacontroller.MediaControllerActivity
import ch.srgssr.pillarbox.player.service.PillarboxMediaSessionService
import ch.srgssr.pillarbox.player.utils.PendingIntentUtils
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/MainNavigation.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/MainNavigation.kt
index ee7836f42..6345c070e 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/MainNavigation.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/MainNavigation.kt
@@ -45,7 +45,7 @@ import androidx.navigation.navigation
import ch.srgssr.pillarbox.analytics.SRGAnalytics
import ch.srgssr.pillarbox.demo.DemoPageView
import ch.srgssr.pillarbox.demo.R
-import ch.srgssr.pillarbox.demo.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
import ch.srgssr.pillarbox.demo.trackPagView
import ch.srgssr.pillarbox.demo.ui.examples.ExamplesHome
import ch.srgssr.pillarbox.demo.ui.integrationLayer.SearchView
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/examples/ExamplesHome.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/examples/ExamplesHome.kt
index 6add80643..8676dfd55 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/examples/ExamplesHome.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/examples/ExamplesHome.kt
@@ -25,8 +25,8 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import ch.srgssr.pillarbox.demo.BuildConfig
-import ch.srgssr.pillarbox.demo.data.DemoItem
-import ch.srgssr.pillarbox.demo.data.Playlist
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.data.Playlist
import ch.srgssr.pillarbox.demo.ui.player.SimplePlayerActivity
import ch.srgssr.pillarbox.demo.ui.theme.PillarboxTheme
@@ -130,7 +130,7 @@ private fun DemoItemView(item: DemoItem, onItemClicked: (DemoItem) -> Unit) {
) {
Text(text = item.title, style = MaterialTheme.typography.bodyMedium)
item.description?.let {
- Text(text = item.description, style = MaterialTheme.typography.labelLarge)
+ Text(text = it, style = MaterialTheme.typography.labelLarge)
}
}
}
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 74a3f3217..04d737ca2 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
@@ -25,7 +25,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import ch.srgssr.pillarbox.demo.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
private val keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Uri)
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/integrationLayer/ContentListsView.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/integrationLayer/ContentListsView.kt
index 4028cf341..f8d235a92 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/integrationLayer/ContentListsView.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/integrationLayer/ContentListsView.kt
@@ -23,7 +23,7 @@ import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import ch.srg.dataProvider.integrationlayer.request.parameters.Bu
import ch.srgssr.pillarbox.demo.DemoPageView
-import ch.srgssr.pillarbox.demo.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
import ch.srgssr.pillarbox.demo.ui.NavigationRoutes
import ch.srgssr.pillarbox.demo.ui.composable
import ch.srgssr.pillarbox.demo.ui.integrationLayer.data.Content
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/SimplePlayerActivity.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/SimplePlayerActivity.kt
index 32209f4d0..1eab732b9 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/SimplePlayerActivity.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/SimplePlayerActivity.kt
@@ -29,9 +29,9 @@ import androidx.lifecycle.repeatOnLifecycle
import androidx.media3.common.Player
import ch.srgssr.pillarbox.analytics.SRGAnalytics
import ch.srgssr.pillarbox.demo.DemoPageView
-import ch.srgssr.pillarbox.demo.data.DemoItem
-import ch.srgssr.pillarbox.demo.data.Playlist
import ch.srgssr.pillarbox.demo.service.DemoPlaybackService
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.data.Playlist
import ch.srgssr.pillarbox.demo.trackPagView
import ch.srgssr.pillarbox.demo.ui.theme.PillarboxTheme
import ch.srgssr.pillarbox.player.service.PlaybackService
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/SimplePlayerViewModel.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/SimplePlayerViewModel.kt
index 2bfc199a6..57caab446 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/SimplePlayerViewModel.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/SimplePlayerViewModel.kt
@@ -15,8 +15,8 @@ import androidx.media3.common.PlaybackParameters
import androidx.media3.common.Player
import androidx.media3.common.Timeline
import androidx.media3.common.VideoSize
-import ch.srgssr.pillarbox.demo.data.DemoItem
-import ch.srgssr.pillarbox.demo.di.PlayerModule
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.di.PlayerModule
import ch.srgssr.pillarbox.player.toRational
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/playlist/MediaItemLibrary.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/playlist/MediaItemLibrary.kt
index 69e0bf197..e263235ad 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/playlist/MediaItemLibrary.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/playlist/MediaItemLibrary.kt
@@ -28,8 +28,8 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
-import ch.srgssr.pillarbox.demo.data.DemoItem
-import ch.srgssr.pillarbox.demo.data.Playlist
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.data.Playlist
import ch.srgssr.pillarbox.demo.ui.theme.PillarboxTheme
/**
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/playlist/PlaylistActionsView.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/playlist/PlaylistActionsView.kt
index a6981274f..80ae5cc37 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/playlist/PlaylistActionsView.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/playlist/PlaylistActionsView.kt
@@ -20,7 +20,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.media3.common.Player
-import ch.srgssr.pillarbox.demo.data.Playlist
+import ch.srgssr.pillarbox.demo.shared.data.Playlist
import ch.srgssr.pillarbox.ui.shuffleModeEnabledAsState
/**
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/ExoPlayerSample.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/ExoPlayerSample.kt
index 0a8d230fb..a37f13131 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/ExoPlayerSample.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/ExoPlayerSample.kt
@@ -8,8 +8,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
-import ch.srgssr.pillarbox.demo.data.DemoItem
-import ch.srgssr.pillarbox.demo.di.PlayerModule
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.di.PlayerModule
import ch.srgssr.pillarbox.ui.ExoPlayerView
/**
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/ShowCaseList.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/ShowCaseList.kt
index 34643a6fa..ad3b28c91 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/ShowCaseList.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/ShowCaseList.kt
@@ -24,7 +24,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import ch.srgssr.pillarbox.demo.R
-import ch.srgssr.pillarbox.demo.data.Playlist
+import ch.srgssr.pillarbox.demo.shared.data.Playlist
import ch.srgssr.pillarbox.demo.ui.NavigationRoutes
import ch.srgssr.pillarbox.demo.ui.player.SimplePlayerActivity
import ch.srgssr.pillarbox.demo.ui.player.mediacontroller.MediaControllerActivity
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/SimplePlayerIntegration.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/SimplePlayerIntegration.kt
index f063438fd..7f755ab35 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/SimplePlayerIntegration.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/SimplePlayerIntegration.kt
@@ -8,8 +8,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
-import ch.srgssr.pillarbox.demo.data.DemoItem
-import ch.srgssr.pillarbox.demo.di.PlayerModule
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.di.PlayerModule
import ch.srgssr.pillarbox.ui.PlayerSurface
/**
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/adaptive/AdaptivePlayer.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/adaptive/AdaptivePlayer.kt
index bfde5c1b2..8306609b3 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/adaptive/AdaptivePlayer.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/adaptive/AdaptivePlayer.kt
@@ -30,8 +30,8 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.media3.common.Player
-import ch.srgssr.pillarbox.demo.data.Playlist
-import ch.srgssr.pillarbox.demo.di.PlayerModule
+import ch.srgssr.pillarbox.demo.shared.data.Playlist
+import ch.srgssr.pillarbox.demo.shared.di.PlayerModule
import ch.srgssr.pillarbox.demo.ui.player.DemoPlayerSurface
import ch.srgssr.pillarbox.ui.ScaleMode
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/multiplayer/MultiPlayerViewModel.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/multiplayer/MultiPlayerViewModel.kt
index 9704b32e4..7aae13ada 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/multiplayer/MultiPlayerViewModel.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/multiplayer/MultiPlayerViewModel.kt
@@ -7,8 +7,8 @@ package ch.srgssr.pillarbox.demo.ui.showcases.multiplayer
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.media3.common.Player
-import ch.srgssr.pillarbox.demo.data.DemoItem
-import ch.srgssr.pillarbox.demo.di.PlayerModule
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.di.PlayerModule
/**
* Multi player view model
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/story/SimpleStory.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/story/SimpleStory.kt
index 66da5ef72..31f16ff82 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/story/SimpleStory.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/story/SimpleStory.kt
@@ -18,9 +18,9 @@ import androidx.media3.common.C
import androidx.media3.common.Player
import androidx.media3.ui.AspectRatioFrameLayout
import androidx.media3.ui.PlayerView
-import ch.srgssr.pillarbox.demo.data.DemoItem
-import ch.srgssr.pillarbox.demo.data.Playlist
-import ch.srgssr.pillarbox.demo.di.PlayerModule
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.data.Playlist
+import ch.srgssr.pillarbox.demo.shared.di.PlayerModule
import ch.srgssr.pillarbox.player.PillarboxPlayer
/**
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/story/StoryViewModel.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/story/StoryViewModel.kt
index cc716875f..98f130269 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/story/StoryViewModel.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/story/StoryViewModel.kt
@@ -9,8 +9,8 @@ import androidx.lifecycle.AndroidViewModel
import androidx.media3.common.C
import androidx.media3.common.Player
import ch.srgssr.pillarbox.core.business.tracker.DefaultMediaItemTrackerRepository
-import ch.srgssr.pillarbox.demo.data.Playlist
-import ch.srgssr.pillarbox.demo.di.PlayerModule
+import ch.srgssr.pillarbox.demo.shared.data.Playlist
+import ch.srgssr.pillarbox.demo.shared.di.PlayerModule
import ch.srgssr.pillarbox.player.PillarboxPlayer
import kotlin.math.ceil
diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/tracking/TrackingToggleSample.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/tracking/TrackingToggleSample.kt
index 41fc49f7f..f3993e213 100644
--- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/tracking/TrackingToggleSample.kt
+++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/tracking/TrackingToggleSample.kt
@@ -21,8 +21,8 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
-import ch.srgssr.pillarbox.demo.data.DemoItem
-import ch.srgssr.pillarbox.demo.di.PlayerModule
+import ch.srgssr.pillarbox.demo.shared.data.DemoItem
+import ch.srgssr.pillarbox.demo.shared.di.PlayerModule
import ch.srgssr.pillarbox.ui.PlayerSurface
/**
diff --git a/pillarbox-player-testutils/build.gradle.kts b/pillarbox-player-testutils/build.gradle.kts
index 4653aaed8..0aba82fa0 100644
--- a/pillarbox-player-testutils/build.gradle.kts
+++ b/pillarbox-player-testutils/build.gradle.kts
@@ -2,6 +2,7 @@
* Copyright (c) 2023. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
+@Suppress("DSL_SCOPE_VIOLATION") // TODO Remove once KTIJ-19369 is fixed
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
diff --git a/pillarbox-player/build.gradle.kts b/pillarbox-player/build.gradle.kts
index 24b302125..879661250 100644
--- a/pillarbox-player/build.gradle.kts
+++ b/pillarbox-player/build.gradle.kts
@@ -2,6 +2,7 @@
* Copyright (c) 2022. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
+@Suppress("DSL_SCOPE_VIOLATION") // TODO Remove once KTIJ-19369 is fixed
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
diff --git a/pillarbox-ui/build.gradle.kts b/pillarbox-ui/build.gradle.kts
index acf03c566..381b24dbf 100644
--- a/pillarbox-ui/build.gradle.kts
+++ b/pillarbox-ui/build.gradle.kts
@@ -2,6 +2,7 @@
* Copyright (c) 2022. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
+@Suppress("DSL_SCOPE_VIOLATION") // TODO Remove once KTIJ-19369 is fixed
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
diff --git a/settings.gradle b/settings.gradle
index e67d79315..5aa3f2050 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -33,3 +33,5 @@ include ':pillarbox-analytics'
include ':pillarbox-core-business'
include ':pillarbox-ui'
include ':pillarbox-player-testutils'
+include ':pillarbox-demo-tv'
+include ':pillarbox-demo-shared'