Update ExoPlayer usage (#3760)

* Switch to StyledPlayerView for migration

* Migrate to media3 for ExoPlayer

* Replace deprecated code

* Restore/customize layout to ExoPlayer v2
This commit is contained in:
Joris Pelgröm 2023-08-05 02:07:52 +02:00 committed by GitHub
parent 77141c254b
commit 49f3080b9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 188 additions and 185 deletions

View File

@ -159,11 +159,9 @@ dependencies {
implementation(libs.biometric)
implementation(libs.webkit)
implementation(libs.exoplayer.core)
implementation(libs.exoplayer.hls)
implementation(libs.exoplayer.ui)
"fullImplementation"(libs.extension.cronet)
"minimalImplementation"(libs.extension.cronet) {
implementation(libs.bundles.media3)
"fullImplementation"(libs.media3.datasource.cronet)
"minimalImplementation"(libs.media3.datasource.cronet) {
exclude(group = "com.google.android.gms", module = "play-services-cronet")
}
"minimalImplementation"(libs.cronet.embedded)

View File

@ -42,15 +42,15 @@ import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.ImageButton
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.result.IntentSenderRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.OptIn
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.ColorUtils
@ -59,17 +59,17 @@ import androidx.core.view.WindowInsetsControllerCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.common.VideoSize
import androidx.media3.datasource.cronet.CronetDataSource
import androidx.media3.exoplayer.DefaultLoadControl
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
import androidx.media3.ui.AspectRatioFrameLayout
import androidx.media3.ui.PlayerView
import androidx.webkit.WebViewCompat
import androidx.webkit.WebViewFeature
import com.google.android.exoplayer2.DefaultLoadControl
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.ext.cronet.CronetDataSource
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout
import com.google.android.exoplayer2.ui.PlayerView
import com.google.android.exoplayer2.video.VideoSize
import dagger.hilt.android.AndroidEntryPoint
import eightbitlab.com.blurview.RenderScriptBlur
import io.homeassistant.companion.android.BaseActivity
@ -85,7 +85,6 @@ import io.homeassistant.companion.android.database.authentication.Authentication
import io.homeassistant.companion.android.database.authentication.AuthenticationDao
import io.homeassistant.companion.android.databinding.ActivityWebviewBinding
import io.homeassistant.companion.android.databinding.DialogAuthenticationBinding
import io.homeassistant.companion.android.databinding.ExoPlayerViewBinding
import io.homeassistant.companion.android.launch.LaunchActivity
import io.homeassistant.companion.android.matter.MatterFrontendCommissioningStatus
import io.homeassistant.companion.android.nfc.WriteNfcTag
@ -118,6 +117,7 @@ import java.util.concurrent.Executors
import javax.inject.Inject
import io.homeassistant.companion.android.common.R as commonR
@OptIn(androidx.media3.common.util.UnstableApi::class)
@AndroidEntryPoint
class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webview.WebView {
@ -196,7 +196,6 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
private lateinit var myCustomView: View
private lateinit var authenticator: Authenticator
private lateinit var exoPlayerView: PlayerView
private lateinit var playerBinding: ExoPlayerViewBinding
private lateinit var windowInsetsController: WindowInsetsControllerCompat
private var mFilePathCallback: ValueCallback<Array<Uri>>? = null
@ -208,13 +207,13 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
private var firstAuthTime: Long = 0
private var resourceURL: String = ""
private var appLocked = true
private var exoPlayer: SimpleExoPlayer? = null
private var exoPlayer: ExoPlayer? = null
private var isExoFullScreen = false
private var exoTop: Int = 0 // These margins are from the DOM and scaled to screen
private var exoLeft: Int = 0
private var exoRight: Int = 0
private var exoBottom: Int = 0
private var exoMute: Boolean = true
private var exoTop = 0 // These margins are from the DOM and scaled to screen
private var exoLeft = 0
private var exoRight = 0
private var exoBottom = 0
private var exoMute = true
private var failedConnection = "external"
private var clearHistory = false
private var moreInfoEntity = ""
@ -253,12 +252,8 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
exoPlayerView.visibility = View.GONE
exoPlayerView.setBackgroundColor(Color.BLACK)
exoPlayerView.alpha = 1f
exoPlayerView.setShowBuffering(PlayerView.SHOW_BUFFERING_ALWAYS)
exoPlayerView.controllerHideOnTouch = true
exoPlayerView.controllerShowTimeoutMs = 2000
playerBinding = ExoPlayerViewBinding.bind(exoPlayerView)
appLocked = presenter.isAppLocked()
binding.blurView.setBlurEnabled(appLocked)
@ -852,7 +847,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
val uri = Uri.parse(payload.getString("url"))
exoMute = payload.optBoolean("muted")
runOnUiThread {
exoPlayer = SimpleExoPlayer.Builder(applicationContext).setMediaSourceFactory(
exoPlayer = ExoPlayer.Builder(applicationContext).setMediaSourceFactory(
DefaultMediaSourceFactory(
CronetDataSource.Factory(
CronetEngine.Builder(applicationContext).enableQuic(true).build(),
@ -872,6 +867,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
exoPlayer?.addListener(object : Player.Listener {
override fun onVideoSizeChanged(videoSize: VideoSize) {
super.onVideoSizeChanged(videoSize)
if (videoSize.height == 0 || videoSize.width == 0) return
exoBottom =
exoTop + ((exoRight - exoLeft) * videoSize.height / videoSize.width)
runOnUiThread {
@ -880,16 +876,15 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
}
})
exoPlayer?.prepare()
exoMute = !exoMute
exoMute = !exoMute // Invert because exoToggleMute() will invert again
exoToggleMute()
exoPlayerView.player = exoPlayer
exoPlayerView.visibility = View.VISIBLE
findViewById<ImageView>(R.id.exo_fullscreen_icon).setOnClickListener {
isExoFullScreen = !isExoFullScreen
exoPlayerView.setFullscreenButtonClickListener { isFullScreen ->
isExoFullScreen = isFullScreen
exoResizeLayout()
}
findViewById<ImageView>(R.id.exo_mute_icon).setOnClickListener { exoToggleMute() }
exoPlayerView.player = exoPlayer
exoPlayerView.visibility = View.VISIBLE
findViewById<ImageButton>(R.id.exo_ha_mute)?.setOnClickListener { exoToggleMute() }
}
webView.externalBus(
id = json.get("id"),
@ -932,20 +927,10 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
exoMute = !exoMute
if (exoMute) {
exoPlayer?.volume = 0f
findViewById<ImageView>(R.id.exo_mute_icon).setImageDrawable(
ContextCompat.getDrawable(
applicationContext,
R.drawable.ic_baseline_volume_off_24
)
)
findViewById<ImageButton>(R.id.exo_ha_mute)?.setImageResource(R.drawable.ic_baseline_volume_off_24)
} else {
exoPlayer?.volume = 1f
findViewById<ImageView>(R.id.exo_mute_icon).setImageDrawable(
ContextCompat.getDrawable(
applicationContext,
R.drawable.ic_baseline_volume_up_24
)
)
findViewById<ImageButton>(R.id.exo_ha_mute)?.setImageResource(R.drawable.ic_baseline_volume_up_24)
}
}
@ -953,22 +938,16 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
val exoLayoutParams = exoPlayerView.layoutParams as FrameLayout.LayoutParams
if (isExoFullScreen) {
if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
playerBinding.exoContentFrame.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL
exoPlayerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL
} else {
playerBinding.exoContentFrame.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH
exoPlayerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH
}
exoLayoutParams.setMargins(0, 0, 0, 0)
exoPlayerView.layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT
exoPlayerView.layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT
findViewById<ImageView>(R.id.exo_fullscreen_icon).setImageDrawable(
ContextCompat.getDrawable(
applicationContext,
R.drawable.ic_baseline_fullscreen_exit_24
)
)
hideSystemUI()
} else {
playerBinding.exoContentFrame.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL
exoPlayerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL
exoPlayerView.layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT
exoPlayerView.layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT
val screenWidth: Int = resources.displayMetrics.widthPixels
@ -979,12 +958,6 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
maxOf(screenWidth - exoRight, 0),
maxOf(screenHeight - exoBottom, 0)
)
findViewById<ImageView>(R.id.exo_fullscreen_icon).setImageDrawable(
ContextCompat.getDrawable(
applicationContext,
R.drawable.ic_baseline_fullscreen_24
)
)
showSystemUI()
}
exoPlayerView.requestLayout()

View File

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M7,14L5,14v5h5v-2L7,17v-3zM5,10h2L7,7h3L10,5L5,5v5zM17,17h-3v2h5v-5h-2v3zM14,5v2h3v3h2L19,5h-5z"/>
</vector>

View File

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M5,16h3v3h2v-5L5,14v2zM8,8L5,8v2h5L10,5L8,5v3zM14,19h2v-3h3v-2h-5v5zM16,8L16,5h-2v5h5L19,8h-3z"/>
</vector>

View File

@ -2,8 +2,7 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v2.21l2.45,2.45c0.03,-0.2 0.05,-0.41 0.05,-0.63zM19,12c0,0.94 -0.2,1.82 -0.54,2.64l1.51,1.51C20.63,14.91 21,13.5 21,12c0,-4.28 -2.99,-7.86 -7,-8.77v2.06c2.89,0.86 5,3.54 5,6.71zM4.27,3L3,4.27 7.73,9L3,9v6h4l5,5v-6.73l4.25,4.25c-0.67,0.52 -1.42,0.93 -2.25,1.18v2.06c1.38,-0.31 2.63,-0.95 3.69,-1.81L19.73,21 21,19.73l-9,-9L4.27,3zM12,4L9.91,6.09 12,8.18L12,4z"/>

View File

@ -2,8 +2,7 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z"/>

View File

@ -20,11 +20,12 @@
android:id="@+id/exoviewGroup"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.exoplayer2.ui.PlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/exoplayerView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.google.android.exoplayer2.ui.PlayerView>
android:layout_height="wrap_content"
app:show_buffering="always">
</androidx.media3.ui.PlayerView>
</FrameLayout>
</RelativeLayout>

View File

@ -1,67 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:id="@+id/exo_play_pause_button"
<!-- Media3 doesn't allow customizing the default player controls, but you can override the layout
file and it will pick up this instead of the library layout. Adjusted from the original layout
https://github.com/androidx/media/blob/a94aa8dbd99fc5ddec6ef25bb4c8ad7b3ca39e6f/libraries/ui/src/main/res/layout/exo_player_control_view.xml
to fit the camera livestream use case / previous (ExoPlayer v2) layout by Home Assistant.
-->
<!-- Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<View android:id="@id/exo_controls_background"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/exo_black_opacity_60"/>
<FrameLayout android:id="@id/exo_bottom_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
<ImageButton android:id="@+id/exo_play"
android:layout_height="24dp" android:layout_width="24dp"
style="@style/ExoMediaButton.Play"/>
<ImageButton android:id="@+id/exo_pause"
android:layout_height="24dp" android:layout_width="24dp"
style="@style/ExoMediaButton.Pause"/>
android:layout_height="@dimen/exo_styled_bottom_bar_height"
android:layout_marginTop="@dimen/exo_styled_bottom_bar_margin_top"
android:layout_gravity="bottom"
android:background="@color/exo_bottom_bar_background"
android:layoutDirection="ltr">
<LinearLayout android:id="@id/exo_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="@dimen/exo_styled_bottom_bar_time_padding"
android:paddingEnd="@dimen/exo_styled_bottom_bar_time_padding"
android:paddingLeft="@dimen/exo_styled_bottom_bar_time_padding"
android:paddingRight="@dimen/exo_styled_bottom_bar_time_padding"
android:layout_gravity="center_vertical|start"
android:layoutDirection="ltr">
<TextView android:id="@id/exo_position"
style="@style/ExoStyledControls.TimeText.Position"/>
<TextView
style="@style/ExoStyledControls.TimeText.Separator"/>
<TextView android:id="@id/exo_duration"
style="@style/ExoStyledControls.TimeText.Duration"/>
</LinearLayout>
<LinearLayout android:id="@id/exo_basic_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:layoutDirection="ltr">
<!-- HA: removed VR/shuffle/repeat/CC/settings buttons, added mute button -->
<ImageButton android:id="@+id/exo_ha_mute"
style="@style/ExoStyledControls.Button.Bottom.HaMute"/>
<ImageButton android:id="@id/exo_fullscreen"
style="@style/ExoStyledControls.Button.Bottom.FullScreen"/>
<ImageButton android:id="@id/exo_overflow_show"
style="@style/ExoStyledControls.Button.Bottom.OverflowShow"/>
</LinearLayout>
<HorizontalScrollView android:id="@id/exo_extra_controls_scroll_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:visibility="invisible">
<LinearLayout android:id="@id/exo_extra_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layoutDirection="ltr">
<ImageButton android:id="@id/exo_overflow_hide"
style="@style/ExoStyledControls.Button.Bottom.OverflowHide"/>
</LinearLayout>
</HorizontalScrollView>
</FrameLayout>
<View android:id="@id/exo_progress_placeholder"
android:layout_width="match_parent"
android:layout_height="@dimen/exo_styled_progress_layout_height"
android:layout_gravity="bottom"
android:layout_marginBottom="@dimen/exo_styled_progress_margin_bottom"/>
<LinearLayout android:id="@id/exo_minimal_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="@dimen/exo_styled_minimal_controls_margin_bottom"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layoutDirection="ltr">
<ImageButton android:id="@id/exo_minimal_fullscreen"
style="@style/ExoStyledControls.Button.Bottom.FullScreen"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="4dp"
android:gravity="bottom"
android:orientation="horizontal">
<TextView android:id="@+id/exo_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textStyle="bold"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:includeFontPadding="false"
android:textColor="#FFBEBEBE"/>
<View android:id="@+id/exo_progress_placeholder"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="24dp"/>
<TextView android:id="@+id/exo_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textStyle="bold"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:includeFontPadding="false"
android:textColor="#FFBEBEBE"/>
<Space
android:layout_width="16dp"
android:layout_height="4dp"/>
<ImageView
android:id="@+id/exo_mute_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/ic_baseline_volume_up_24"/>
<Space
android:layout_width="16dp"
android:layout_height="4dp"/>
<ImageView
android:id="@+id/exo_fullscreen_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/ic_baseline_fullscreen_24"/>
android:id="@id/exo_center_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@android:color/transparent"
android:gravity="center"
android:padding="@dimen/exo_styled_controls_padding"
android:clipToPadding="false"
android:layoutDirection="ltr">
<!-- HA: removed prev/rewind -->
<ImageButton android:id="@id/exo_play_pause"
style="@style/ExoStyledControls.Button.Center.PlayPause"/>
<!-- HA: removed ffwd/next -->
</LinearLayout>
</FrameLayout>
</merge>

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000">
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout android:id="@+id/exo_content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<ProgressBar
android:id="@+id/exo_buffering"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:indeterminate="true"
/>
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
<com.google.android.exoplayer2.ui.PlayerControlView android:id="@+id/exo_controller"
android:layout_height="match_parent"
android:layout_width="match_parent">
</com.google.android.exoplayer2.ui.PlayerControlView>
</FrameLayout>

View File

@ -131,4 +131,9 @@
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
<style name="ExoStyledControls.Button.Bottom.HaMute">
<item name="android:src">@drawable/ic_baseline_volume_up_24</item>
<item name="android:contentDescription">@string/mute_unmute</item>
</style>
</resources>

View File

@ -188,11 +188,9 @@ dependencies {
implementation(libs.biometric)
implementation(libs.webkit)
implementation(libs.exoplayer.core)
implementation(libs.exoplayer.hls)
implementation(libs.exoplayer.ui)
"fullImplementation"(libs.extension.cronet)
"minimalImplementation"(libs.extension.cronet) {
implementation(libs.bundles.media3)
"fullImplementation"(libs.media3.datasource.cronet)
"minimalImplementation"(libs.media3.datasource.cronet) {
exclude(group = "com.google.android.gms", module = "play-services-cronet")
}
"minimalImplementation"(libs.cronet.embedded)

View File

@ -397,6 +397,7 @@
<string name="message_no_connected_nodes">No connected Wear devices, please make sure Bluetooth is on and your watch is paired.</string>
<string name="message_some_installed">The Wear app is installed on some of your Wear devices: (%1$s)\n\nClick the button below to install the app on the other devices.</string>
<string name="missing_command_permission">Please open the Home Assistant app and send the command again in order to grant the proper permissions. You will be taken to a page to either grant the Home Assistant app the permission, or you will need to select Permissions from the details page and then grant the missing permission. For command_bluetooth the name of the permission is Nearby devices. If you are attempting to use command_activity to make a phone call you will also need to grant Phone permissions.</string>
<string name="mute_unmute">Mute/Unmute</string>
<string name="areas">Areas</string>
<string name="more_entities">More entities</string>
<string name="need_help">Need Help?</string>

View File

@ -23,7 +23,6 @@ converterJackson = "2.9.0"
coreKtx = "1.10.1"
cronet-embedded = "113.5672.61"
emojiJava = "5.1.1"
exoplayer = "2.19.0"
firebase-bom = "32.2.0"
firebaseAppdistributionGradle = "4.0.0"
fragment-ktx = "1.6.1"
@ -40,6 +39,7 @@ ktlint = "11.5.0"
lifecycle = "2.6.1"
loggingInterceptor = "4.11.0"
material = "1.9.0"
media3 = "1.1.0"
navigation-compose = "2.6.0"
okhttp = "4.11.0"
picasso = "2.8"
@ -110,10 +110,6 @@ converter-jackson = { module = "com.squareup.retrofit2:converter-jackson", versi
core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }
cronet-embedded = { module = "org.chromium.net:cronet-embedded", version.ref = "cronet-embedded" }
emojiJava = { module = "com.vdurmont:emoji-java", version.ref = "emojiJava" }
extension-cronet = { module = "com.google.android.exoplayer:extension-cronet", version.ref = "exoplayer" }
exoplayer-ui = { module = "com.google.android.exoplayer:exoplayer-ui", version.ref = "exoplayer" }
exoplayer-hls = { module = "com.google.android.exoplayer:exoplayer-hls", version.ref = "exoplayer" }
exoplayer-core = { module = "com.google.android.exoplayer:exoplayer-core", version.ref = "exoplayer" }
firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebase-bom" }
firebase-messaging = { module = "com.google.firebase:firebase-messaging" }
fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "fragment-ktx" }
@ -134,6 +130,10 @@ logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", ver
navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigation-compose" }
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
material = { module = "com.google.android.material:material", version.ref = "material" }
media3-datasource-cronet = { module = "androidx.media3:media3-datasource-cronet", version.ref = "media3" }
media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "media3" }
media3-exoplayer-hls = { module = "androidx.media3:media3-exoplayer-hls", version.ref = "media3" }
media3-ui = { module = "androidx.media3:media3-ui", version.ref = "media3" }
play-services-threadnetwork = { module = "com.google.android.gms:play-services-threadnetwork", version.ref = "play-services-threadnetwork" }
play-services-home = { module = "com.google.android.gms:play-services-home", version.ref = "play-services-home" }
play-services-location = { module = "com.google.android.gms:play-services-location", version.ref = "play-services-location" }
@ -154,3 +154,6 @@ wear-remote-interactions = { module = "androidx.wear:wear-remote-interactions",
wear-tiles-material = { module = "androidx.wear.tiles:tiles-material", version.ref = "wear-tiles" }
wear-tiles = { module = "androidx.wear.tiles:tiles", version.ref = "wear-tiles" }
webkit = { module = "androidx.webkit:webkit", version.ref = "webkit" }
[bundles]
media3 = ["media3-exoplayer", "media3-exoplayer-hls", "media3-ui"]