This commit is contained in:
Derek Schmidt 2020-06-21 00:00:28 +00:00 committed by GitHub
commit 19843bf351
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 7 deletions

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.apognu.otter">
xmlns:tools="http://schemas.android.com/tools"
package="com.github.apognu.otter">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
@ -17,6 +18,13 @@
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<meta-data
android:name="com.google.android.gms.car.notification.SmallIcon"
android:resource="@drawable/ottershape" />
<meta-data android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc"/>
<!-- <meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.google.android.exoplayer2.ext.cast.DefaultCastOptionsProvider"/> -->
@ -45,7 +53,14 @@
<activity android:name="com.github.apognu.otter.activities.SettingsActivity" />
<activity android:name="com.github.apognu.otter.activities.LicencesActivity" />
<service android:name="com.github.apognu.otter.playback.PlayerService" />
<service
android:name="com.github.apognu.otter.playback.PlayerService"
android:exported="true"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<service
android:name=".playback.PinService"

View File

@ -1,18 +1,21 @@
package com.github.apognu.otter.playback
import android.annotation.SuppressLint
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.media.AudioAttributes
import android.media.AudioFocusRequest
import android.media.AudioManager
import android.net.Uri
import android.os.Build
import android.os.IBinder
import android.os.Bundle
import android.support.v4.media.MediaBrowserCompat
import android.support.v4.media.MediaDescriptionCompat
import android.support.v4.media.session.MediaSessionCompat
import android.view.KeyEvent
import com.github.apognu.otter.Otter
import androidx.media.MediaBrowserServiceCompat
import com.github.apognu.otter.R
import com.github.apognu.otter.utils.*
import com.google.android.exoplayer2.C
@ -20,6 +23,7 @@ import com.google.android.exoplayer2.ExoPlaybackException
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator
import com.google.android.exoplayer2.source.TrackGroupArray
import com.google.android.exoplayer2.trackselection.TrackSelectionArray
import kotlinx.coroutines.Dispatchers.IO
@ -30,7 +34,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
class PlayerService : Service() {
class PlayerService : MediaBrowserServiceCompat() {
private lateinit var queue: QueueManager
private val jobs = mutableListOf<Job>()
@ -84,8 +88,21 @@ class PlayerService : Service() {
isActive = true
}
sessionToken = mediaSession.sessionToken
mediaControlsManager = MediaControlsManager(this, mediaSession)
val queueNavigator: TimelineQueueNavigator = object : TimelineQueueNavigator(mediaSession) {
override fun getMediaDescription(player: Player, windowIndex: Int): MediaDescriptionCompat {
val track = queue.get(windowIndex)
return MediaDescriptionCompat.Builder().apply {
setTitle(track.title)
setSubtitle(track.subtitle())
setIconUri(Uri.parse(maybeNormalizeUrl(track.cover())))
}.build()
}
}
player = SimpleExoPlayer.Builder(this).build().apply {
playWhenReady = false
@ -95,6 +112,7 @@ class PlayerService : Service() {
MediaSessionConnector(mediaSession).also {
it.setPlayer(this)
it.setQueueNavigator(queueNavigator)
it.setMediaButtonEventHandler { player, _, mediaButtonEvent ->
mediaButtonEvent.extras?.getParcelable<KeyEvent>(Intent.EXTRA_KEY_EVENT)?.let { key ->
if (key.action == KeyEvent.ACTION_UP) {
@ -219,8 +237,6 @@ class PlayerService : Service() {
})
}
override fun onBind(intent: Intent?): IBinder? = null
@SuppressLint("NewApi")
override fun onDestroy() {
jobs.forEach { it.cancel() }
@ -430,4 +446,20 @@ class PlayerService : Service() {
}
}
}
override fun onGetRoot(
clientPackageName: String,
clientUid: Int,
rootHints: Bundle?
): BrowserRoot? {
return BrowserRoot("/", null)
}
override fun onLoadChildren(
parentId: String,
result: Result<List<MediaBrowserCompat.MediaItem>>
) {
val list = mutableListOf<MediaBrowserCompat.MediaItem>()
result.sendResult(list)
}
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<automotiveApp>
<uses name="media"/>
</automotiveApp>