Skip to content

Commit

Permalink
Android Auto: Fixed and improved search
Browse files Browse the repository at this point in the history
Search now queries data from server. Results are grouped by books, series and authors.
  • Loading branch information
ISO-B committed Nov 8, 2024
1 parent 8134ec8 commit eedcd18
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -404,3 +404,22 @@ data class LibraryItemWithEpisode(
var libraryItemWrapper:LibraryItemWrapper,
var episode:PodcastEpisode
)

@JsonIgnoreProperties(ignoreUnknown = true)
data class LibraryItemSearchResultSeriesItemType(
var series: LibrarySeriesItem,
var books: List<LibraryItem>?
)

@JsonIgnoreProperties(ignoreUnknown = true)
data class LibraryItemSearchResultLibraryItemType(
val libraryItem: LibraryItem
)

@JsonIgnoreProperties(ignoreUnknown = true)
data class LibraryItemSearchResultType(
var book:List<LibraryItemSearchResultLibraryItemType>?,
var podcast:List<LibraryItemSearchResultLibraryItemType>?,
var series:List<LibraryItemSearchResultSeriesItemType>?,
var authors:List<LibraryAuthorItem>?
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import android.net.Uri
import android.os.Bundle
import android.support.v4.media.MediaDescriptionCompat
import androidx.media.utils.MediaConstants
import com.audiobookshelf.app.BuildConfig
import com.audiobookshelf.app.R
import com.audiobookshelf.app.device.DeviceManager
Expand All @@ -15,7 +16,6 @@ class LibraryAuthorItem(
id:String,
var libraryId:String,
var name:String,
var lastFirst:String,
var description:String?,
var imagePath:String?,
var addedAt:Long,
Expand All @@ -40,8 +40,11 @@ class LibraryAuthorItem(
}

@JsonIgnore
override fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context): MediaDescriptionCompat {
fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context, groupTitle: String?): MediaDescriptionCompat {
val extras = Bundle()
if (groupTitle !== null) {
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, groupTitle)
}

val mediaId = "__LIBRARY__${libraryId}__AUTHOR__${id}"
return MediaDescriptionCompat.Builder()
Expand All @@ -52,4 +55,9 @@ class LibraryAuthorItem(
.setExtras(extras)
.build()
}

@JsonIgnore
override fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context): MediaDescriptionCompat {
return getMediaDescription(progress, ctx, null)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class LibraryItem(
}

@JsonIgnore
fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context, authorId: String?, showSeriesNumber: Boolean?): MediaDescriptionCompat {
fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context, authorId: String?, showSeriesNumber: Boolean?, groupTitle: String?): MediaDescriptionCompat {
val extras = Bundle()

if (collapsedSeries == null) {
Expand Down Expand Up @@ -124,6 +124,9 @@ class LibraryItem(
)
}
}
if (groupTitle !== null) {
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, groupTitle)
}

val mediaId = if (localLibraryItemId != null) {
localLibraryItemId
Expand Down Expand Up @@ -153,16 +156,21 @@ class LibraryItem(
.build()
}

@JsonIgnore
fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context, authorId: String?, showSeriesNumber: Boolean?): MediaDescriptionCompat {
return getMediaDescription(progress, ctx, authorId, showSeriesNumber, null)
}

@JsonIgnore
fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context, authorId: String?): MediaDescriptionCompat {
return getMediaDescription(progress, ctx, authorId, null)
return getMediaDescription(progress, ctx, authorId, null, null)
}

@JsonIgnore
override fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context): MediaDescriptionCompat {
/*
This is needed so Android auto library hierarchy for author series can be implemented
*/
return getMediaDescription(progress, ctx, null, null)
return getMediaDescription(progress, ctx, null, null, null)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.audiobookshelf.app.data
import android.content.Context
import android.os.Bundle
import android.support.v4.media.MediaDescriptionCompat
import androidx.media.utils.MediaConstants
import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.annotation.JsonIgnoreProperties

Expand All @@ -29,7 +30,7 @@ class LibrarySeriesItem(
}

@JsonIgnore
override fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context): MediaDescriptionCompat {
fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context, groupTitle: String?): MediaDescriptionCompat {
val extras = Bundle()

if (localLibraryItemId != null) {
Expand All @@ -38,6 +39,9 @@ class LibrarySeriesItem(
MediaDescriptionCompat.STATUS_DOWNLOADED
)
}
if (groupTitle !== null) {
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, groupTitle)
}

val mediaId = "__LIBRARY__${libraryId}__SERIES__${id}"
return MediaDescriptionCompat.Builder()
Expand All @@ -48,4 +52,9 @@ class LibrarySeriesItem(
.setExtras(extras)
.build()
}

@JsonIgnore
override fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context): MediaDescriptionCompat {
return getMediaDescription(progress, ctx, null)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,14 @@ class MediaManager(private var apiHandler: ApiHandler, var ctx: Context) {
}
}

suspend fun searchLocalCache(libraryId: String, queryString: String) : LibraryItemSearchResultType? {
return suspendCoroutine {
apiHandler.getSearchResults(libraryId, queryString) { results ->
it.resume(results)
}
}
}

fun getFirstItem() : LibraryItemWrapper? {
if (serverLibraryItems.isNotEmpty()) {
return serverLibraryItems[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.source.hls.HlsMediaSource
import com.google.android.exoplayer2.ui.PlayerNotificationManager
import com.google.android.exoplayer2.upstream.*
import kotlinx.coroutines.runBlocking
import java.util.*
import kotlin.concurrent.schedule

Expand Down Expand Up @@ -1350,13 +1351,55 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {

override fun onSearch(query: String, extras: Bundle?, result: Result<MutableList<MediaBrowserCompat.MediaItem>>) {
result.detach()
mediaManager.loadAndroidAutoItems {
browseTree = BrowseTree(this, mediaManager.serverItemsInProgress, mediaManager.serverLibraries)
val children = browseTree[LIBRARIES_ROOT]?.map { item ->
MediaBrowserCompat.MediaItem(item.description, MediaBrowserCompat.MediaItem.FLAG_BROWSABLE)
Log.d(tag, "Search bundle: $extras")
var foundBooks: MutableList<MediaBrowserCompat.MediaItem> = mutableListOf()
var foundPodcasts: MutableList<MediaBrowserCompat.MediaItem> = mutableListOf()
var foundSeries: MutableList<MediaBrowserCompat.MediaItem> = mutableListOf()
var foundAuthors: MutableList<MediaBrowserCompat.MediaItem> = mutableListOf()

mediaManager.serverLibraries.forEach { serverLibrary ->
runBlocking{
val searchResult = mediaManager.searchLocalCache(serverLibrary.id, query)
Log.d(tag, "onSearch: SearchResult: $searchResult")
if (searchResult === null) return@runBlocking
if (searchResult.book !== null && searchResult.book!!.isNotEmpty()) {
Log.d(tag, "onSearch: found ${searchResult.book!!.size} books")
val children = searchResult.book!!.map { bookResult ->
val libraryItem = bookResult.libraryItem
val progress = mediaManager.serverUserMediaProgress.find { it.libraryItemId == libraryItem.id }
val localLibraryItem = DeviceManager.dbManager.getLocalLibraryItemByLId(libraryItem.id)
libraryItem.localLibraryItemId = localLibraryItem?.id
val description = libraryItem.getMediaDescription(progress, ctx, null, null, "Books (${serverLibrary.name})")
MediaBrowserCompat.MediaItem(description, MediaBrowserCompat.MediaItem.FLAG_PLAYABLE)
}
foundBooks.addAll(children)
}
if (searchResult.series !== null && searchResult.series!!.isNotEmpty()) {
Log.d(tag, "onSearch: found ${searchResult.series!!.size} series")
val children = searchResult.series!!.map { seriesResult ->
val seriesItem = seriesResult.series
seriesItem.books = seriesResult.books as MutableList<LibraryItem>
val description = seriesItem.getMediaDescription(null, ctx, "Series (${serverLibrary.name})")
MediaBrowserCompat.MediaItem(description, MediaBrowserCompat.MediaItem.FLAG_BROWSABLE)
}
foundSeries.addAll(children)
}
if (searchResult.authors !== null && searchResult.authors!!.isNotEmpty()) {
Log.d(tag, "onSearch: found ${searchResult.authors!!.size} authors")
val children = searchResult.authors!!.map { authorItem ->
val description = authorItem.getMediaDescription(null, ctx, "Authors (${serverLibrary.name})")
MediaBrowserCompat.MediaItem(description, MediaBrowserCompat.MediaItem.FLAG_BROWSABLE)
}
foundAuthors.addAll(children)
}
Log.d(tag, "onSearch: Library ${serverLibrary.id} processed")
}
result.sendResult(children as MutableList<MediaBrowserCompat.MediaItem>?)
Log.d(tag, "onSearch: Library ${serverLibrary.id} scanned")
}
foundBooks.addAll(foundSeries)
foundBooks.addAll(foundAuthors)
result.sendResult(foundBooks as MutableList<MediaBrowserCompat.MediaItem>?)
Log.d(tag, "onSearch: Done")
}

//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,19 @@ class ApiHandler(var ctx:Context) {
}
}

fun getSearchResults(libraryId:String, queryString:String, cb: (LibraryItemSearchResultType?) -> Unit) {
Log.d(tag, "Doing search for library $libraryId")
getRequest("/api/libraries/$libraryId/search?q=$queryString", null, null) {
if (it.has("error")) {
Log.e(tag, it.getString("error") ?: "getSearchResults Failed")
cb(null)
} else {
val librarySearchResults = jacksonMapper.readValue<LibraryItemSearchResultType>(it.toString())
cb(librarySearchResults)
}
}
}

fun getAllItemsInProgress(cb: (List<ItemInProgress>) -> Unit) {
getRequest("/api/me/items-in-progress", null, null) {
val items = mutableListOf<ItemInProgress>()
Expand Down

0 comments on commit eedcd18

Please sign in to comment.