Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.focus.FocusRequester
Expand Down Expand Up @@ -101,7 +100,6 @@ fun NavigableApplication(content: @Composable () -> Unit) {
private val selectionKeys = setOf(Key.DirectionCenter, Key.Enter)

// Courtesy of https://github.com/thesauri/dpad-compose/blob/main/app/src/main/java/dev/berggren/DpadFocusable.kt
@ExperimentalComposeUiApi
fun Modifier.navigable(
onClick: (() -> Unit)? = null,
onClickLabel: String? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ fun MenuIcon(
modifier: Modifier = Modifier,
enabled: Boolean = true,
iconTint: Color = iconColor(enabled),
iconModifier: Modifier = Modifier,
label: String? = null,
labelColor: Color = labelColor(enabled),
labelModifier: Modifier = Modifier,
Expand All @@ -163,7 +164,7 @@ fun MenuIcon(
Icon(
painter = iconPainter,
contentDescription = contentDescription,
modifier = Modifier.size(topMenuIconSize),
modifier = iconModifier.then(Modifier.size(topMenuIconSize)),
tint = iconTint,
)
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
package com.lasthopesoftware.bluewater.client.browsing.library.settings

sealed interface StoredConnectionSettings
sealed interface StoredConnectionSettings {
val customHeaders: Map<String, String>
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ data class StoredMediaCenterConnectionSettings(
val isWakeOnLanEnabled: Boolean = false,
val sslCertificateFingerprint: String? = null,
val macAddress: String? = null,
override val customHeaders: Map<String, String> = emptyMap(),
) : StoredConnectionSettings
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ data class StoredSubsonicConnectionSettings(
val isWakeOnLanEnabled: Boolean = false,
val sslCertificateFingerprint: String? = null,
val macAddress: String? = null,
override val customHeaders: Map<String, String> = emptyMap(),
) : StoredConnectionSettings
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ data class MediaCenterConnectionDetails(
val baseUrl: URL,
val authCode: String? = null,
val certificateFingerprint: ByteArray = emptyByteArray,
val customHeaders: Map<String, String> = emptyMap(),
) {
constructor(authCode: String?, ipAddress: String?, port: Int)
: this(URL(IoCommon.httpUriScheme, ipAddress, port, ""), authCode)
constructor(authCode: String?, ipAddress: String?, port: Int, customHeaders: Map<String, String> = emptyMap())
: this(baseUrl = URL(IoCommon.httpUriScheme, ipAddress, port, ""), authCode = authCode, customHeaders = customHeaders)

constructor(authCode: String?, ipAddress: String?, port: Int, certificateFingerprint: ByteArray)
: this(URL(IoCommon.httpsUriScheme, ipAddress, port, ""), authCode, certificateFingerprint)
constructor(authCode: String?, ipAddress: String?, port: Int, certificateFingerprint: ByteArray, customHeaders: Map<String, String> = emptyMap())
: this(URL(IoCommon.httpsUriScheme, ipAddress, port, ""), authCode, certificateFingerprint, customHeaders)

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand All @@ -24,6 +25,7 @@ data class MediaCenterConnectionDetails(
if (baseUrl != other.baseUrl) return false
if (authCode != other.authCode) return false
if (!certificateFingerprint.contentEquals(other.certificateFingerprint)) return false
if (customHeaders != other.customHeaders) return false

return true
}
Expand All @@ -32,6 +34,7 @@ data class MediaCenterConnectionDetails(
var result = baseUrl.hashCode()
result = 31 * result + (authCode?.hashCode() ?: 0)
result = 31 * result + certificateFingerprint.contentHashCode()
result = 31 * result + customHeaders.hashCode()
return result
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ data class SubsonicConnectionDetails(
val password: String,
val salt: String = "",
val certificateFingerprint: ByteArray = emptyByteArray,
val customHeaders: Map<String, String> = emptyMap()
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand All @@ -21,6 +22,7 @@ data class SubsonicConnectionDetails(
if (password != other.password) return false
if (salt != other.salt) return false
if (!certificateFingerprint.contentEquals(other.certificateFingerprint)) return false
if (customHeaders != other.customHeaders) return false

return true
}
Expand All @@ -31,6 +33,7 @@ data class SubsonicConnectionDetails(
result = 31 * result + password.hashCode()
result = 31 * result + salt.hashCode()
result = 31 * result + certificateFingerprint.contentHashCode()
result = 31 * result + customHeaders.hashCode()
return result
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class KtorFactory(private val context: Context) : ProvideHttpPromiseClients {
}
).toPromise()

inner class MediaCenterClient() : ProvideHttpPromiseServerClients<MediaCenterConnectionDetails> {
inner class MediaCenterClient : ProvideHttpPromiseServerClients<MediaCenterConnectionDetails> {

override fun promiseServerClient(connectionDetails: MediaCenterConnectionDetails): Promise<HttpPromiseClient> =
KtorPromiseClient(scope, CIO, getHttpConfiguration(connectionDetails), getEngineConfig(connectionDetails)).toPromise()
Expand Down Expand Up @@ -150,6 +150,7 @@ class KtorFactory(private val context: Context) : ProvideHttpPromiseClients {
mediaCenterConnectionDetails.authCode.takeUnless { it.isNullOrEmpty() }?.let { "basic $it" }.also {
install(createClientPlugin("BasicAuth") {
onRequest { request, _ ->
request.headers.appendAll(mediaCenterConnectionDetails.customHeaders)
request.header(HttpHeaders.Authorization, it)
}
})
Expand All @@ -164,7 +165,7 @@ class KtorFactory(private val context: Context) : ProvideHttpPromiseClients {
}
}

inner class SubsonicClient() : ProvideHttpPromiseServerClients<SubsonicConnectionDetails> {
inner class SubsonicClient : ProvideHttpPromiseServerClients<SubsonicConnectionDetails> {
override fun promiseServerClient(connectionDetails: SubsonicConnectionDetails): Promise<HttpPromiseClient> =
KtorPromiseClient(
scope,
Expand Down Expand Up @@ -208,6 +209,8 @@ class KtorFactory(private val context: Context) : ProvideHttpPromiseClients {

install(createClientPlugin("SubsonicParams") {
onRequest { request, _ ->
request.headers.appendAll(subsonicConnectionDetails.customHeaders)

request.url {
with(subsonicConnectionDetails) {
parameters["u"] = userName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ class OkHttpFactory(private val context: Context) : ProvideHttpPromiseClients {
private val dispatcher by lazy { Dispatcher(ThreadPools.io) }
private fun OkHttpClient.Builder.configureForStreaming() =
readTimeout(45.seconds).retryOnConnectionFailure(false)
private fun Request.Builder.addHeaders(headers: Map<String, String>) {
for ((key, value) in headers)
addHeader(key, value)
}
}

private val commonClient by lazy {
Expand Down Expand Up @@ -100,7 +104,7 @@ class OkHttpFactory(private val context: Context) : ProvideHttpPromiseClients {
return "$applicationName/$versionName (Linux;Android ${Build.VERSION.RELEASE})"
}

inner class MediaCenterClient() : ProvideHttpPromiseServerClients<MediaCenterConnectionDetails> {
inner class MediaCenterClient : ProvideHttpPromiseServerClients<MediaCenterConnectionDetails> {
override fun promiseServerClient(connectionDetails: MediaCenterConnectionDetails): Promise<HttpPromiseClient> =
OkHttpPromiseClient(getOkHttpClient(connectionDetails)).toPromise()

Expand Down Expand Up @@ -129,6 +133,9 @@ class OkHttpFactory(private val context: Context) : ProvideHttpPromiseClients {
.addNetworkInterceptor { chain ->
val requestBuilder = chain.request().newBuilder()
requestBuilder.header("Authorization", authHeaderValue)

requestBuilder.addHeaders(mediaCenterConnectionDetails.customHeaders)

chain.proceed(requestBuilder.build())
}
.build()
Expand Down Expand Up @@ -188,7 +195,7 @@ class OkHttpFactory(private val context: Context) : ProvideHttpPromiseClients {
}
}

inner class SubsonicClient() : ProvideHttpPromiseServerClients<SubsonicConnectionDetails> {
inner class SubsonicClient : ProvideHttpPromiseServerClients<SubsonicConnectionDetails> {
override fun promiseServerClient(connectionDetails: SubsonicConnectionDetails): Promise<HttpPromiseClient> =
OkHttpPromiseClient(getOkHttpClient(connectionDetails)).toPromise()

Expand Down Expand Up @@ -219,6 +226,7 @@ class OkHttpFactory(private val context: Context) : ProvideHttpPromiseClients {
val requestBuilder = chain.request().newBuilder()

requestBuilder.url(chain.request().url.toUrl().addParams(*addedParams))
requestBuilder.addHeaders(subsonicConnectionDetails.customHeaders)

chain.proceed(requestBuilder.build())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ class LiveServerConnectionProvider(
authKey,
ip,
httpsPort,
certificateFingerprint
certificateFingerprint,
settings.customHeaders,
)
)
}
Expand All @@ -93,6 +94,7 @@ class LiveServerConnectionProvider(
authKey,
ip,
httpPort,
settings.customHeaders,
)
)
}
Expand All @@ -106,6 +108,7 @@ class LiveServerConnectionProvider(
authKey,
ip,
httpPort,
settings.customHeaders,
)
)
}
Expand Down Expand Up @@ -151,7 +154,8 @@ class LiveServerConnectionProvider(
settings.userName,
settings.password,
salt,
certificateFingerprint
certificateFingerprint,
settings.customHeaders,
)
)
}
Expand All @@ -165,7 +169,8 @@ class LiveServerConnectionProvider(
settings.userName,
settings.password,
salt,
certificateFingerprint
certificateFingerprint,
settings.customHeaders,
)
)
}
Expand All @@ -177,7 +182,8 @@ class LiveServerConnectionProvider(
settings.userName,
settings.password,
salt,
certificateFingerprint
certificateFingerprint,
settings.customHeaders,
)
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
package com.lasthopesoftware.bluewater.client.connection.settings

sealed interface ConnectionSettings
sealed interface ConnectionSettings {
val customHeaders: Map<String, String>
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class ConnectionSettingsLookup(private val librarySettings: ProvideLibrarySettin
override fun promiseConnectionSettings(libraryId: LibraryId): Promise<ConnectionSettings?> =
librarySettings
.promiseLibrarySettings(libraryId)
.then { it ->
.then {
it?.connectionSettings?.run {
when (this) {
is StoredMediaCenterConnectionSettings -> MediaCenterConnectionSettings(
Expand All @@ -22,14 +22,17 @@ class ConnectionSettingsLookup(private val librarySettings: ProvideLibrarySettin
isLocalOnly = isLocalOnly,
isWakeOnLanEnabled = isWakeOnLanEnabled,
sslCertificateFingerprint = sslCertificateFingerprint?.hexToByteArray() ?: emptyByteArray,
macAddress = macAddress)
macAddress = macAddress,
customHeaders = customHeaders,
)
is StoredSubsonicConnectionSettings -> SubsonicConnectionSettings(
url = url ?: "",
userName = userName ?: "",
password = password ?: "",
isWakeOnLanEnabled = isWakeOnLanEnabled,
sslCertificateFingerprint = sslCertificateFingerprint?.hexToByteArray() ?: emptyByteArray,
macAddress = macAddress,
customHeaders = customHeaders,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ data class MediaCenterConnectionSettings(
val isWakeOnLanEnabled: Boolean = false,
val sslCertificateFingerprint: ByteArray = emptyByteArray,
val macAddress: String? = null,
override val customHeaders: Map<String, String> = emptyMap(),
) : ConnectionSettings {
override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand All @@ -26,6 +27,7 @@ data class MediaCenterConnectionSettings(
if (isWakeOnLanEnabled != other.isWakeOnLanEnabled) return false
if (!sslCertificateFingerprint.contentEquals(other.sslCertificateFingerprint)) return false
if (macAddress != other.macAddress) return false
if (customHeaders != other.customHeaders) return false

return true
}
Expand All @@ -38,6 +40,7 @@ data class MediaCenterConnectionSettings(
result = 31 * result + isWakeOnLanEnabled.hashCode()
result = 31 * result + sslCertificateFingerprint.contentHashCode()
result = 31 * result + (macAddress?.hashCode() ?: 0)
result = 31 * result + customHeaders.hashCode()
return result
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ data class SubsonicConnectionSettings(
val isWakeOnLanEnabled: Boolean = false,
val sslCertificateFingerprint: ByteArray = emptyByteArray,
val macAddress: String? = null,
override val customHeaders: Map<String, String> = emptyMap(),
) : ConnectionSettings {
override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand All @@ -22,8 +23,9 @@ data class SubsonicConnectionSettings(
if (url != other.url) return false
if (userName != other.userName) return false
if (password != other.password) return false
if (!sslCertificateFingerprint.contentEquals(other.sslCertificateFingerprint)) return false
if (macAddress != other.macAddress) return false
if (!sslCertificateFingerprint.contentEquals(other.sslCertificateFingerprint)) return false
if (customHeaders != other.customHeaders) return false

return true
}
Expand All @@ -35,6 +37,7 @@ data class SubsonicConnectionSettings(
result = 31 * result + password.hashCode()
result = 31 * result + sslCertificateFingerprint.contentHashCode()
result = 31 * result + (macAddress?.hashCode() ?: 0)
result = 31 * result + customHeaders.hashCode()
return result
}
}
Loading