Skip to content

Commit 0eaf8e7

Browse files
committed
Merge branch 'feature/android-auto-2'
2 parents 6f15417 + 85a65e8 commit 0eaf8e7

19 files changed

Lines changed: 738 additions & 21 deletions

File tree

README-CHANGES.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,8 +1168,14 @@
11681168
</c:change>
11691169
</c:changes>
11701170
</c:release>
1171-
<c:release date="2026-04-14T15:04:41+00:00" is-open="true" ticket-system="org.lyrasis.jira" version="1.28.0">
1172-
<c:changes/>
1171+
<c:release date="2026-04-16T12:20:23+00:00" is-open="true" ticket-system="org.lyrasis.jira" version="1.28.0">
1172+
<c:changes>
1173+
<c:change date="2026-04-16T12:20:23+00:00" summary="Support Android Auto.">
1174+
<c:tickets>
1175+
<c:ticket id="PP-3535"/>
1176+
</c:tickets>
1177+
</c:change>
1178+
</c:changes>
11731179
</c:release>
11741180
</c:releases>
11751181
<c:ticket-systems>

palace-app-palace/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ dependencies {
459459
implementation(libs.androidx.datastore.preferences.external.protobuf)
460460
implementation(libs.androidx.documentfile)
461461
implementation(libs.androidx.drawerlayout)
462+
implementation(libs.androidx.exifinterface)
462463
implementation(libs.androidx.emoji2)
463464
implementation(libs.androidx.emoji2.views)
464465
implementation(libs.androidx.emoji2.views.helper)

palace-app-palace/src/main/AndroidManifest.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@
7676
android:name="org.apache.http.legacy"
7777
android:required="false" />
7878

79+
<uses-library
80+
android:name="androidx.car.app"
81+
android:required="false" />
82+
83+
<meta-data
84+
android:name="com.google.android.gms.car.application"
85+
android:resource="@xml/automotive_app_desc" />
86+
7987
<activity
8088
android:name="org.nypl.simplified.ui.errorpage.ErrorPageActivity"
8189
android:configChanges="orientation"
@@ -119,6 +127,17 @@
119127
<service
120128
android:name="org.librarysimplified.http.network_access.LSHTTPNetworkAvailabilityService"
121129
android:exported="false" />
130+
131+
<service
132+
android:name="org.nypl.simplified.ui.auto.PalaceMediaBrowserService"
133+
android:exported="true"
134+
android:foregroundServiceType="mediaPlayback">
135+
136+
<intent-filter>
137+
<action android:name="androidx.media3.session.MediaLibraryService" />
138+
<action android:name="android.media.browse.MediaBrowserService" />
139+
</intent-filter>
140+
</service>
122141
</application>
123142

124143
</manifest>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
3+
<automotiveApp>
4+
<uses name="media" />
5+
</automotiveApp>

palace-books-controller/src/main/java/org/nypl/simplified/books/controller/ProfileAccountLoginTask.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ class ProfileAccountLoginTask(
464464
request: BasicToken
465465
): TaskResult<Unit> {
466466
val authenticationURI = request.description.authenticationURI
467+
this.steps.addAttribute("AuthenticationURI", authenticationURI.toString())
467468

468469
val httpRequest = this.http.newRequest(authenticationURI)
469470
.setAuthorization(

palace-tests/src/test/java/org/nypl/simplified/tests/pdf/PdfViewerProviderTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import org.mockito.Mockito
88
import org.nypl.simplified.books.api.Book
99
import org.nypl.simplified.books.api.BookFormat
1010
import org.nypl.simplified.viewer.spi.ViewerParameters
11+
import java.util.UUID
1112

1213
class PdfViewerProviderTest {
1314

1415
@Test
1516
fun supportsPdfBooks() {
1617
val preferences = ViewerParameters(
1718
flags = mapOf(),
19+
viewerID = UUID.randomUUID(),
1820
onLoginRequested = {
1921

2022
}

palace-ui/build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ dependencies {
160160
implementation(libs.kotlinx.coroutines.android)
161161
implementation(libs.kotlinx.coroutines.core.jvm)
162162
implementation(libs.logback.android)
163+
implementation(libs.media3.common)
164+
implementation(libs.media3.datasource)
165+
implementation(libs.media3.exoplayer)
166+
implementation(libs.media3.extractor)
167+
implementation(libs.media3.session)
163168
implementation(libs.palace.audiobook.feedbooks)
164169
implementation(libs.palace.audiobook.time.tracking)
165170
implementation(libs.palace.audiobook.views)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.nypl.simplified.ui.auto
2+
3+
import org.nypl.simplified.threads.NamedThreadPools
4+
5+
/**
6+
* A background thread used by Android Auto media operations.
7+
*/
8+
9+
object PalaceAutoThread {
10+
11+
val executor =
12+
NamedThreadPools.namedThreadPool(1, "palace-auto", 0)
13+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.nypl.simplified.ui.auto
2+
3+
import androidx.media3.session.MediaLibraryService
4+
import androidx.media3.session.MediaSession
5+
import org.librarysimplified.audiobook.views.mediacontrols.PlayerMediaFacade
6+
import org.slf4j.LoggerFactory
7+
8+
class PalaceMediaBrowserService : MediaLibraryService() {
9+
10+
private val logger =
11+
LoggerFactory.getLogger(PalaceMediaBrowserService::class.java)
12+
13+
private lateinit var session: MediaLibrarySession
14+
15+
override fun onCreate() {
16+
this.logger.debug("onCreate")
17+
18+
try {
19+
super.onCreate()
20+
this.session =
21+
MediaLibrarySession.Builder(this, PlayerMediaFacade, PalaceMediaLibraryCallback())
22+
.build()
23+
} catch (e: Throwable) {
24+
this.logger.debug("onCreate: ", e)
25+
}
26+
}
27+
28+
override fun onGetSession(
29+
controllerInfo: MediaSession.ControllerInfo
30+
): MediaLibrarySession {
31+
this.logger.debug("onGetSession")
32+
return this.session
33+
}
34+
35+
override fun onDestroy() {
36+
this.logger.debug("onDestroy")
37+
38+
try {
39+
this.session.release()
40+
super.onDestroy()
41+
} catch (e: Throwable) {
42+
this.logger.debug("onDestroy: ", e)
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)