TP-78922 | Neil | Revert Exoplayer changes from super app (#12144)
This commit is contained in:
@@ -7,15 +7,9 @@
|
||||
|
||||
package com.naviapp.app
|
||||
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.database.StandaloneDatabaseProvider
|
||||
import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor
|
||||
import androidx.media3.datasource.cache.SimpleCache
|
||||
import coil.ImageLoader
|
||||
import coil.ImageLoaderFactory
|
||||
import com.navi.base.cache.repository.NaviCacheRepository
|
||||
import com.navi.common.media3simplecache.Media3SimpleCache
|
||||
import com.navi.pay.common.setup.NaviPayManager
|
||||
import com.naviapp.app.facades.ThirdPartyObjectProvider
|
||||
import com.naviapp.app.initializers.ComponentInitializer
|
||||
@@ -24,11 +18,10 @@ import com.naviapp.home.common.setup.NotificationManager
|
||||
import com.naviapp.utils.isDifferentPackage
|
||||
import dagger.Lazy
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltAndroidApp
|
||||
class NaviApplication : BaseApplication(), ImageLoaderFactory, Media3SimpleCache {
|
||||
class NaviApplication : BaseApplication(), ImageLoaderFactory {
|
||||
companion object {
|
||||
lateinit var instance: NaviApplication
|
||||
}
|
||||
@@ -45,8 +38,6 @@ class NaviApplication : BaseApplication(), ImageLoaderFactory, Media3SimpleCache
|
||||
|
||||
@Inject lateinit var thirdPartyObjectProvider: ThirdPartyObjectProvider
|
||||
|
||||
@OptIn(UnstableApi::class) private lateinit var media3SimpleCache: SimpleCache
|
||||
|
||||
private val isDifferentPackageValue: Boolean by lazy {
|
||||
isDifferentPackage(this@NaviApplication)
|
||||
}
|
||||
@@ -82,18 +73,4 @@ class NaviApplication : BaseApplication(), ImageLoaderFactory, Media3SimpleCache
|
||||
|
||||
override fun newImageLoader(): ImageLoader =
|
||||
thirdPartyObjectProvider.createImageLoader(applicationContext)
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
override fun getMedia3SimpleCache(): SimpleCache {
|
||||
if (::media3SimpleCache.isInitialized.not()) {
|
||||
val downloadContentDirectory = File(this.getExternalFilesDir(null), "downloads")
|
||||
media3SimpleCache =
|
||||
SimpleCache(
|
||||
downloadContentDirectory,
|
||||
LeastRecentlyUsedCacheEvictor(100_000_000),
|
||||
StandaloneDatabaseProvider(this)
|
||||
)
|
||||
}
|
||||
return media3SimpleCache
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,7 @@ package com.naviapp.home.compose.uiTron.renderer
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.navi.common.uitron.model.property.VideoViewProperty
|
||||
import com.navi.common.uitron.model.ui.CommonCustomViewType
|
||||
import com.navi.common.uitron.render.CommonCustomUiTronRenderer
|
||||
import com.navi.common.uitron.render.VideoViewRenderer
|
||||
import com.navi.uitron.model.data.UiTronData
|
||||
import com.navi.uitron.model.ui.UiTronView
|
||||
import com.navi.uitron.render.UiTronRenderer
|
||||
@@ -72,17 +69,6 @@ class HomeCustomUiTronRenderer(private val homeScrollState: () -> ScrollState) :
|
||||
)
|
||||
}
|
||||
}
|
||||
CommonCustomViewType.VideoView.name -> {
|
||||
(composeView.property as? VideoViewProperty)?.let {
|
||||
VideoViewRenderer(parentScrollState = homeScrollState)
|
||||
.Render(
|
||||
property = it,
|
||||
uiTronData = dataMap?.getOrElse(it.layoutId.orEmpty()) { null },
|
||||
uiTronViewModel = uiTronViewModel,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
super.Render(composeView, modifier, dataMap, uiTronViewModel)
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ androidx-gridlayout = "1.0.0"
|
||||
androidx-hilt = "1.0.0"
|
||||
androidx-legacy-support-v4 = "1.0.0"
|
||||
androidx-lifecycle = "2.6.2"
|
||||
androidx-media3 = "1.4.0"
|
||||
androidx-macro-benchmark = "1.2.4"
|
||||
androidx-multidex = "2.0.1"
|
||||
androidx-pagingCompose = "3.2.0"
|
||||
@@ -209,9 +208,6 @@ androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-ru
|
||||
androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidx-lifecycle" }
|
||||
androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }
|
||||
|
||||
androidx-media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "androidx-media3" }
|
||||
androidx-media3-ui = { module = "androidx.media3:media3-ui", version.ref = "androidx-media3" }
|
||||
|
||||
androidx-multidex = { module = "androidx.multidex:multidex", version.ref = "androidx-multidex" }
|
||||
|
||||
androidx-navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "navigation" }
|
||||
|
||||
@@ -77,12 +77,6 @@ dependencies {
|
||||
api libs.androidx.camera.lifecycle
|
||||
api libs.androidx.camera.view
|
||||
api libs.androidx.lifecycle.runtime.compose
|
||||
api(libs.androidx.media3.exoplayer) {
|
||||
exclude(group: "com.google.guava", module: "guava")
|
||||
}
|
||||
api(libs.androidx.media3.ui) {
|
||||
exclude(group: "com.google.guava", module: "guava")
|
||||
}
|
||||
api libs.androidx.room.runtime
|
||||
api libs.androidx.room.ktx
|
||||
api libs.anrwatchdog
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.common.media3simplecache
|
||||
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.datasource.cache.SimpleCache
|
||||
|
||||
/**
|
||||
* An interface for providing access to a [SimpleCache] instance.
|
||||
*
|
||||
* This interface is useful for abstracting the creation and management of a [SimpleCache] instance,
|
||||
* allowing for flexibility in how it is implemented and accessed.
|
||||
*/
|
||||
interface Media3SimpleCache {
|
||||
/**
|
||||
* Returns a [SimpleCache] instance.
|
||||
*
|
||||
* This function is marked with `@OptIn(UnstableApi::class)` because the SimpleCache API is
|
||||
* currently unstable and subject to change.
|
||||
*
|
||||
* @return A [SimpleCache] instance.
|
||||
*/
|
||||
@OptIn(UnstableApi::class) fun getMedia3SimpleCache(): SimpleCache
|
||||
}
|
||||
@@ -10,7 +10,6 @@ package com.navi.common.uitron.deserializer
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonElement
|
||||
import com.navi.common.adverse.model.AdverseViewData
|
||||
import com.navi.common.uitron.model.data.VideoViewData
|
||||
import com.navi.common.uitron.model.ui.CommonCustomViewType
|
||||
import com.navi.naviwidgets.utils.VIEW_TYPE
|
||||
import com.navi.uitron.deserializer.UiTronDataDeserializer
|
||||
@@ -32,9 +31,6 @@ open class CommonUiTronDataDeserializer : UiTronDataDeserializer() {
|
||||
CommonCustomViewType.AdverseView.name -> {
|
||||
context?.deserialize(jsonObject, AdverseViewData::class.java)
|
||||
}
|
||||
CommonCustomViewType.VideoView.name -> {
|
||||
context?.deserialize(jsonObject, VideoViewData::class.java)
|
||||
}
|
||||
else -> super.deserialize(json, typeOfT, context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ package com.navi.common.uitron.deserializer
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonElement
|
||||
import com.navi.common.adverse.model.AdverseViewProperty
|
||||
import com.navi.common.uitron.model.property.VideoViewProperty
|
||||
import com.navi.common.uitron.model.ui.CommonCustomViewType
|
||||
import com.navi.uitron.deserializer.ComposePropertyDeserializer
|
||||
import com.navi.uitron.model.ui.BaseProperty
|
||||
@@ -32,9 +31,6 @@ open class CommonUiTronPropertyDeserializer : ComposePropertyDeserializer() {
|
||||
CommonCustomViewType.AdverseView.name -> {
|
||||
return context?.deserialize(jsonObject, AdverseViewProperty::class.java)
|
||||
}
|
||||
CommonCustomViewType.VideoView.name -> {
|
||||
return context?.deserialize(jsonObject, VideoViewProperty::class.java)
|
||||
}
|
||||
else -> super.deserialize(json, typeOfT, context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.common.uitron.model.data
|
||||
|
||||
import com.navi.uitron.model.data.UiTronData
|
||||
|
||||
data class VideoViewData(
|
||||
val videoUrl: String? = null,
|
||||
val repeatMode: String? = null,
|
||||
) : UiTronData()
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.common.uitron.model.property
|
||||
|
||||
import com.navi.uitron.model.ui.BaseProperty
|
||||
|
||||
class VideoViewProperty : BaseProperty()
|
||||
@@ -8,6 +8,5 @@
|
||||
package com.navi.common.uitron.model.ui
|
||||
|
||||
enum class CommonCustomViewType {
|
||||
AdverseView,
|
||||
VideoView,
|
||||
AdverseView
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import com.navi.adverse.sdk.adverseState.AdverseStateCallbacks
|
||||
import com.navi.adverse.sdk.ui.AdverseView
|
||||
import com.navi.common.adverse.model.AdverseViewData
|
||||
import com.navi.common.uitron.model.property.VideoViewProperty
|
||||
import com.navi.common.uitron.model.ui.CommonCustomViewType
|
||||
import com.navi.uitron.model.data.UiTronData
|
||||
import com.navi.uitron.model.ui.UiTronView
|
||||
@@ -65,17 +64,6 @@ open class CommonCustomUiTronRenderer : CustomUiTronRenderer {
|
||||
}
|
||||
)
|
||||
}
|
||||
CommonCustomViewType.VideoView.name -> {
|
||||
(composeView.property as? VideoViewProperty)?.let {
|
||||
VideoViewRenderer()
|
||||
.Render(
|
||||
property = it,
|
||||
uiTronData = dataMap?.getOrElse(it.layoutId.orEmpty()) { null },
|
||||
uiTronViewModel = uiTronViewModel,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.common.uitron.render
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.layout.layoutId
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.Player.STATE_READY
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.datasource.DefaultDataSource
|
||||
import androidx.media3.datasource.DefaultHttpDataSource
|
||||
import androidx.media3.datasource.FileDataSource
|
||||
import androidx.media3.datasource.cache.CacheDataSink
|
||||
import androidx.media3.datasource.cache.CacheDataSource
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
import androidx.media3.exoplayer.source.MediaSource
|
||||
import androidx.media3.exoplayer.source.ProgressiveMediaSource
|
||||
import androidx.media3.ui.AspectRatioFrameLayout.RESIZE_MODE_ZOOM
|
||||
import androidx.media3.ui.PlayerView
|
||||
import com.navi.base.AppServiceManager
|
||||
import com.navi.base.utils.orTrue
|
||||
import com.navi.common.media3simplecache.Media3SimpleCache
|
||||
import com.navi.common.uitron.model.data.VideoViewData
|
||||
import com.navi.common.uitron.model.property.VideoViewProperty
|
||||
import com.navi.uitron.model.data.UiTronData
|
||||
import com.navi.uitron.render.Renderer
|
||||
import com.navi.uitron.utils.clip
|
||||
import com.navi.uitron.utils.customClickable
|
||||
import com.navi.uitron.utils.customCombinedClick
|
||||
import com.navi.uitron.utils.customOffset
|
||||
import com.navi.uitron.utils.setBackground
|
||||
import com.navi.uitron.utils.setBlur
|
||||
import com.navi.uitron.utils.setHeight
|
||||
import com.navi.uitron.utils.setHeightRange
|
||||
import com.navi.uitron.utils.setPadding
|
||||
import com.navi.uitron.utils.setTag
|
||||
import com.navi.uitron.utils.setWidth
|
||||
import com.navi.uitron.utils.setWidthRange
|
||||
import com.navi.uitron.viewmodel.UiTronViewModel
|
||||
|
||||
class VideoViewRenderer(private val parentScrollState: (() -> ScrollState)? = null) :
|
||||
Renderer<VideoViewProperty> {
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
@Composable
|
||||
override fun Render(
|
||||
property: VideoViewProperty,
|
||||
uiTronData: UiTronData?,
|
||||
uiTronViewModel: UiTronViewModel,
|
||||
modifier: Modifier?
|
||||
) {
|
||||
super.Render(property, uiTronData, uiTronViewModel, modifier)
|
||||
val videoViewData = uiTronData as? VideoViewData
|
||||
|
||||
if (property.visible.orTrue()) {
|
||||
val viewModifier =
|
||||
(modifier ?: Modifier)
|
||||
.setTag(property)
|
||||
.layoutId(property.layoutId.orEmpty())
|
||||
.customOffset(property.offset)
|
||||
.setWidth(property.width)
|
||||
.setHeight(property.height)
|
||||
.setWidthRange(property.widthRange)
|
||||
.setHeightRange(property.heightRange)
|
||||
.setPadding(property.margin)
|
||||
.setBackground(
|
||||
property.backgroundColor,
|
||||
property.shape,
|
||||
property.backGroundBrushData
|
||||
)
|
||||
.clip(property.clipShape)
|
||||
.setPadding(property.padding)
|
||||
.customClickable(
|
||||
{ uiTronViewModel.handleActions(uiTronData?.onClick) },
|
||||
actions = uiTronData?.onClick?.actions,
|
||||
property = property
|
||||
)
|
||||
.customCombinedClick(property, uiTronData) { uiTronViewModel.handleActions(it) }
|
||||
.graphicsLayer { alpha = property.alpha ?: 1.0f }
|
||||
.setBlur(property.blurData)
|
||||
|
||||
val localContext = LocalContext.current
|
||||
|
||||
val mediaUrl = remember(videoViewData?.videoUrl) { videoViewData?.videoUrl.orEmpty() }
|
||||
|
||||
val exoplayerRepeatMode =
|
||||
remember(videoViewData?.repeatMode) {
|
||||
when (videoViewData?.repeatMode) {
|
||||
"ONE" -> ExoPlayer.REPEAT_MODE_ONE
|
||||
"ALL" -> ExoPlayer.REPEAT_MODE_ALL
|
||||
"OFF" -> ExoPlayer.REPEAT_MODE_OFF
|
||||
else -> ExoPlayer.REPEAT_MODE_OFF
|
||||
}
|
||||
}
|
||||
|
||||
val placeholderVisibility = remember { mutableStateOf(true) }
|
||||
|
||||
exoPlayer =
|
||||
remember(mediaUrl, exoplayerRepeatMode) {
|
||||
ExoPlayer.Builder(localContext).build().apply {
|
||||
setMediaSource(getProgressiveMediaSource(localContext, mediaUrl))
|
||||
repeatMode = exoplayerRepeatMode
|
||||
volume = 0f
|
||||
prepare()
|
||||
addListener(
|
||||
object : Player.Listener {
|
||||
override fun onPlaybackStateChanged(playbackState: Int) {
|
||||
super.onPlaybackStateChanged(playbackState)
|
||||
if (playbackState == STATE_READY) {
|
||||
play()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRenderedFirstFrame() {
|
||||
super.onRenderedFirstFrame()
|
||||
if (placeholderVisibility.value) {
|
||||
placeholderVisibility.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val playerView =
|
||||
remember(exoPlayer) {
|
||||
PlayerView(localContext).apply {
|
||||
useController = false
|
||||
player = exoPlayer
|
||||
resizeMode = RESIZE_MODE_ZOOM
|
||||
}
|
||||
}
|
||||
|
||||
Box {
|
||||
AndroidView(modifier = viewModifier, factory = { playerView })
|
||||
if (placeholderVisibility.value) {
|
||||
Box(viewModifier.background(Color.White))
|
||||
}
|
||||
}
|
||||
|
||||
parentScrollState?.let { if (it.invoke().isScrollInProgress) pause() else play() }
|
||||
|
||||
val lifecycleOwner = rememberUpdatedState(LocalLifecycleOwner.current)
|
||||
|
||||
DisposableEffect(lifecycleOwner.value) { onDispose { releasePlayer() } }
|
||||
}
|
||||
}
|
||||
|
||||
private var exoPlayer: ExoPlayer? = null
|
||||
|
||||
private fun releasePlayer() {
|
||||
exoPlayer?.apply {
|
||||
playWhenReady = false
|
||||
release()
|
||||
}
|
||||
exoPlayer = null
|
||||
}
|
||||
|
||||
private fun pause() {
|
||||
exoPlayer?.playWhenReady = false
|
||||
}
|
||||
|
||||
private fun play() {
|
||||
exoPlayer?.playWhenReady = true
|
||||
}
|
||||
|
||||
companion object {
|
||||
@OptIn(UnstableApi::class)
|
||||
private fun getProgressiveMediaSource(context: Context, mediaUrl: String): MediaSource {
|
||||
val downloadCache =
|
||||
(AppServiceManager.application as Media3SimpleCache).getMedia3SimpleCache()
|
||||
val cacheSink = CacheDataSink.Factory().setCache(downloadCache)
|
||||
val downstreamFactory = FileDataSource.Factory()
|
||||
val upstreamFactory =
|
||||
DefaultDataSource.Factory(context, DefaultHttpDataSource.Factory())
|
||||
|
||||
val dataSourceFactory =
|
||||
CacheDataSource.Factory()
|
||||
.setCache(downloadCache)
|
||||
.setCacheWriteDataSinkFactory(cacheSink)
|
||||
.setCacheReadDataSourceFactory(downstreamFactory)
|
||||
.setUpstreamDataSourceFactory(upstreamFactory)
|
||||
.setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)
|
||||
|
||||
return ProgressiveMediaSource.Factory(dataSourceFactory)
|
||||
.createMediaSource(MediaItem.fromUri(Uri.parse(mediaUrl)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ package com.navi.common.uitron.serializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.navi.common.adverse.model.AdverseViewData
|
||||
import com.navi.common.uitron.model.data.VideoViewData
|
||||
import com.navi.common.uitron.model.ui.CommonCustomViewType
|
||||
import com.navi.uitron.model.data.UiTronData
|
||||
import com.navi.uitron.serializer.UiTronDataSerializer
|
||||
@@ -28,9 +27,6 @@ open class CommonUiTronDataSerializer : UiTronDataSerializer() {
|
||||
CommonCustomViewType.AdverseView.name -> {
|
||||
context?.serialize(src as AdverseViewData, AdverseViewData::class.java)
|
||||
}
|
||||
CommonCustomViewType.VideoView.name -> {
|
||||
context?.serialize(src as VideoViewData, VideoViewData::class.java)
|
||||
}
|
||||
else -> super.serialize(src, typeOfSrc, context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ package com.navi.common.uitron.serializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.navi.common.adverse.model.AdverseViewProperty
|
||||
import com.navi.common.uitron.model.property.VideoViewProperty
|
||||
import com.navi.common.uitron.model.ui.CommonCustomViewType
|
||||
import com.navi.uitron.model.ui.BaseProperty
|
||||
import com.navi.uitron.serializer.ComposePropertySerializer
|
||||
@@ -28,9 +27,6 @@ open class CommonUiTronPropertySerializer : ComposePropertySerializer() {
|
||||
CommonCustomViewType.AdverseView.name -> {
|
||||
context?.serialize(src as AdverseViewProperty, AdverseViewProperty::class.java)
|
||||
}
|
||||
CommonCustomViewType.VideoView.name -> {
|
||||
context?.serialize(src as VideoViewProperty, VideoViewProperty::class.java)
|
||||
}
|
||||
else -> super.serialize(src, typeOfSrc, context)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user