Skip to content

Commit ee010e7

Browse files
authored
Merge pull request #552 from namehillsoftware/bugfix/empty-connection-settings
[Bugfix] Empty Connection Settings
2 parents 518d2cd + 40fe8fb commit ee010e7

8 files changed

Lines changed: 58 additions & 77 deletions

File tree

projectBlueWater/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ dependencies {
199199
implementation "androidx.media3:media3-datasource-okhttp:$media3_version"
200200
implementation 'com.squareup.okio:okio:3.10.2'
201201
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.14'
202-
implementation 'com.namehillsoftware:querydroid:0.5.0'
202+
implementation 'com.namehillsoftware:querydroid:0.5.2'
203203
implementation "androidx.compose.ui:ui:$compose_version"
204204
implementation "androidx.compose.material:material:$compose_version"
205205
implementation "androidx.compose.ui:ui-tooling:$compose_version"

projectBlueWater/src/main/java/com/lasthopesoftware/bluewater/client/browsing/library/access/LibraryRepository.kt

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -103,20 +103,17 @@ class LibraryRepository(private val context: Context) : ManageLibraries, Provide
103103
if (cancellationSignal.isCancelled) throw CancellationException("Cancelled while saving library")
104104

105105
return RepositoryAccessHelper(context).use { repositoryAccessHelper ->
106-
repositoryAccessHelper.beginTransaction().use { closeableTransaction ->
107-
val isLibraryExists = library.id > -1
106+
val isLibraryExists = library.id > -1
108107

109-
val returnLibrary =
110-
if (isLibraryExists) repositoryAccessHelper.update(tableName, library)
111-
else repositoryAccessHelper.insert(tableName, library)
108+
val returnLibrary =
109+
if (isLibraryExists) repositoryAccessHelper.update(tableName, library)
110+
else repositoryAccessHelper.insert(tableName, library)
112111

113-
if (BuildConfig.DEBUG) {
114-
logger.debug("Library saved.")
115-
}
116-
117-
closeableTransaction.setTransactionSuccessful()
118-
returnLibrary
112+
if (BuildConfig.DEBUG) {
113+
logger.debug("Library saved.")
119114
}
115+
116+
returnLibrary
120117
}
121118
}
122119
}
@@ -137,18 +134,14 @@ class LibraryRepository(private val context: Context) : ManageLibraries, Provide
137134
if (libraryInt < 0) return
138135

139136
RepositoryAccessHelper(context).use { repositoryAccessHelper ->
140-
repositoryAccessHelper.beginTransaction().use { closeableTransaction ->
141-
val result = SqLiteAssistants.updateValue(repositoryAccessHelper.writableDatabase, tableName, values)
137+
val result = SqLiteAssistants.updateValue(repositoryAccessHelper.writableDatabase, tableName, values)
142138

143-
if (result == 0L) {
144-
throw IOException("Updating $tableName for id ${values.id} returned 0 rows.")
145-
}
146-
147-
if (BuildConfig.DEBUG) {
148-
logger.debug("Now Playing updated for library {}.", libraryInt)
149-
}
139+
if (result == 0L) {
140+
throw IOException("Updating $tableName for id ${values.id} returned 0 rows.")
141+
}
150142

151-
closeableTransaction.setTransactionSuccessful()
143+
if (BuildConfig.DEBUG) {
144+
logger.debug("Now Playing updated for library {}.", libraryInt)
152145
}
153146
}
154147
}

projectBlueWater/src/main/java/com/lasthopesoftware/bluewater/client/playback/engine/PlaybackEngine.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.lasthopesoftware.bluewater.client.playback.engine
22

3-
import androidx.lifecycle.AtomicReference
43
import com.lasthopesoftware.bluewater.client.browsing.files.ServiceFile
54
import com.lasthopesoftware.bluewater.client.browsing.library.repository.LibraryId
65
import com.lasthopesoftware.bluewater.client.playback.engine.bootstrap.BootstrapPlayback
@@ -35,6 +34,7 @@ import com.namehillsoftware.handoff.promises.Promise
3534
import org.jetbrains.annotations.Contract
3635
import org.joda.time.Duration
3736
import java.util.concurrent.CancellationException
37+
import java.util.concurrent.atomic.AtomicReference
3838
import kotlin.math.max
3939

4040
class PlaybackEngine(

projectBlueWater/src/main/java/com/lasthopesoftware/bluewater/client/playback/engine/bootstrap/ManagedPlaylistPlayer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.lasthopesoftware.bluewater.client.playback.engine.bootstrap
22

3-
import androidx.lifecycle.AtomicReference
43
import com.lasthopesoftware.bluewater.client.browsing.library.repository.LibraryId
54
import com.lasthopesoftware.bluewater.client.playback.engine.preparation.ManagePlaybackQueues
65
import com.lasthopesoftware.bluewater.client.playback.file.PositionedPlayableFile
@@ -18,6 +17,7 @@ import com.lasthopesoftware.promises.extensions.toPromise
1817
import com.lasthopesoftware.resources.closables.PromisingCloseable
1918
import com.namehillsoftware.handoff.promises.Promise
2019
import org.joda.time.Duration
20+
import java.util.concurrent.atomic.AtomicReference
2121

2222
class ManagedPlaylistPlayer(
2323
private val volumeManagement: PlaylistVolumeManager,

projectBlueWater/src/main/java/com/lasthopesoftware/bluewater/client/playback/file/exoplayer/ExoPlayerPlaybackHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.lasthopesoftware.bluewater.client.playback.file.exoplayer
22

33
import androidx.annotation.OptIn
4-
import androidx.lifecycle.AtomicReference
54
import androidx.media3.common.ParserException
65
import androidx.media3.common.PlaybackException
76
import androidx.media3.common.Player
@@ -24,6 +23,7 @@ import org.joda.time.Duration
2423
import org.joda.time.format.PeriodFormatterBuilder
2524
import java.io.EOFException
2625
import java.net.ProtocolException
26+
import java.util.concurrent.atomic.AtomicReference
2727
import kotlin.coroutines.cancellation.CancellationException
2828

2929
class ExoPlayerPlaybackHandler(private val exoPlayer: PromisingExoPlayer) :
Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
package com.lasthopesoftware.bluewater.shared.android.ui
22

3-
import androidx.compose.foundation.ExperimentalFoundationApi
4-
import androidx.compose.foundation.gestures.AnchoredDraggableState
5-
import androidx.compose.runtime.Composable
6-
import androidx.compose.runtime.State
7-
import androidx.compose.runtime.derivedStateOf
8-
import androidx.compose.runtime.remember
93
import androidx.compose.ui.unit.Dp
104

115
fun linearInterpolation(initial: Dp, final: Dp, progress: Float): Dp =
@@ -16,8 +10,3 @@ fun linearInterpolation(initial: Float, final: Float, progress: Float): Float =
1610

1711
fun calculateProgress(initial: Float, final: Float, currentPosition: Float): Float =
1812
((currentPosition - initial) / (final - initial)).coerceIn(0f, 1f)
19-
20-
@OptIn(ExperimentalFoundationApi::class)
21-
val <T> AnchoredDraggableState<T>.absoluteProgressState: State<Float>
22-
@Composable
23-
get() = remember { derivedStateOf { (requireOffset() - anchors.minAnchor()) / anchors.maxAnchor() } }

projectBlueWater/src/test/java/com/lasthopesoftware/bluewater/client/playback/engine/GivenAPlayingPlaybackEngine/AndPlaybackErrors/When Playback is Resumed.kt

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import com.lasthopesoftware.bluewater.client.playback.nowplaying.storage.NowPlay
2020
import com.lasthopesoftware.bluewater.client.playback.nowplaying.storage.NowPlayingRepository
2121
import com.lasthopesoftware.bluewater.client.playback.volume.PlaylistVolumeManager
2222
import com.lasthopesoftware.bluewater.shared.promises.extensions.toExpiringFuture
23+
import com.lasthopesoftware.promises.extensions.toPromise
2324
import com.namehillsoftware.handoff.Messenger
2425
import com.namehillsoftware.handoff.promises.Promise
2526
import io.mockk.every
@@ -35,12 +36,28 @@ class `When Playback is Resumed` {
3536
private val finalPlaybackPreparer = FinalPlaybackPreparer()
3637

3738
private val mut by lazy {
38-
val deferredPlaybackPreparer = DeferredPlaybackPreparer()
39-
4039
val fakePlaybackPreparerProvider = mockk<IPlayableFilePreparationSourceProvider> {
41-
every { providePlayableFilePreparationSource() } returns deferredPlaybackPreparer andThen finalPlaybackPreparer
42-
43-
every { maxQueueSize } returns 1
40+
every { providePlayableFilePreparationSource() } returns mockk {
41+
every { promisePreparedPlaybackFile(LibraryId(libraryId), ServiceFile("1"), Duration.ZERO) } returns
42+
FakePreparedPlayableFile(
43+
ResolvablePlaybackHandler().apply { resolve() }
44+
).toPromise()
45+
46+
every { promisePreparedPlaybackFile(LibraryId(libraryId), ServiceFile("2"), Duration.ZERO) } returns
47+
FakePreparedPlayableFile(
48+
ResolvablePlaybackHandler().apply { resolve() }
49+
).toPromise()
50+
51+
every { promisePreparedPlaybackFile(LibraryId(libraryId), ServiceFile("3"), Duration.ZERO) } returns
52+
FakePreparedPlayableFile(
53+
ResolvablePlaybackHandler().apply {
54+
setCurrentPosition(164)
55+
reject(Exception("f"))
56+
}
57+
).toPromise()
58+
} andThen finalPlaybackPreparer
59+
60+
every { maxQueueSize } returns 0
4461
}
4562

4663
val library = Library(id = libraryId)
@@ -69,7 +86,7 @@ class `When Playback is Resumed` {
6986
playbackBootstrapper,
7087
)
7188

72-
Triple(deferredPlaybackPreparer, nowPlayingRepository, playbackEngine)
89+
Pair(nowPlayingRepository, playbackEngine)
7390
}
7491

7592
private var error: PlaybackException? = null
@@ -79,13 +96,15 @@ class `When Playback is Resumed` {
7996

8097
@BeforeAll
8198
fun act() {
82-
val (deferredErrorPlaybackPreparer, nowPlayingRepository, playbackEngine) = mut
99+
val (nowPlayingRepository, playbackEngine) = mut
83100

84101
val promisedError = Promise {
85102
playbackEngine
86103
.setOnPlaylistError { e ->
87104
if (e is PlaybackException) {
88105
it.sendResolution(e)
106+
} else {
107+
it.sendRejection(e)
89108
}
90109
}
91110
}
@@ -105,14 +124,6 @@ class `When Playback is Resumed` {
105124
.toExpiringFuture()
106125
.get()
107126

108-
deferredErrorPlaybackPreparer.resolve().resolve()
109-
110-
deferredErrorPlaybackPreparer.resolve().resolve()
111-
with (deferredErrorPlaybackPreparer.resolve()) {
112-
setCurrentPosition(164)
113-
reject(Exception("f"))
114-
}
115-
116127
error = promisedError.toExpiringFuture().get()
117128
nowPlaying = nowPlayingRepository.promiseNowPlaying(LibraryId(libraryId)).toExpiringFuture().get()
118129
isPlayingBeforeResume = playbackEngine.isPlaying
@@ -122,10 +133,10 @@ class `When Playback is Resumed` {
122133
.setOnPlayingFileChanged { _, p ->
123134
it.sendResolution(p)
124135
}
125-
}
126136

127-
playbackEngine.resume().toExpiringFuture().get()
128-
finalPlaybackPreparer.resolve()
137+
playbackEngine.resume().toExpiringFuture().get()
138+
finalPlaybackPreparer.resolve()
139+
}
129140

130141
positionedPlayingFile = promisedFile.toExpiringFuture().get()
131142
}
@@ -155,23 +166,6 @@ class `When Playback is Resumed` {
155166
assertThat(isPlayingBeforeResume).isFalse()
156167
}
157168

158-
private open class DeferredPlaybackPreparer : PlayableFilePreparationSource {
159-
private var messenger: Messenger<PreparedPlayableFile?>? = null
160-
161-
fun resolve(): ResolvablePlaybackHandler {
162-
val playbackHandler = ResolvablePlaybackHandler()
163-
messenger?.sendResolution(FakePreparedPlayableFile(playbackHandler))
164-
return playbackHandler
165-
}
166-
167-
override fun promisePreparedPlaybackFile(
168-
libraryId: LibraryId,
169-
serviceFile: ServiceFile,
170-
preparedAt: Duration): Promise<PreparedPlayableFile?> = Promise { messenger ->
171-
this.messenger = messenger
172-
}
173-
}
174-
175169
private class FinalPlaybackPreparer : PlayableFilePreparationSource {
176170

177171
val playbackHandler = ResolvablePlaybackHandler()

projectBlueWater/src/test/java/com/lasthopesoftware/bluewater/client/playback/engine/GivenAPlayingPlaybackEngine/AndPlaybackIsPaused/AndTheTrackIsChanged/When Playback Is Resumed.kt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class `When Playback Is Resumed` {
5050
val preparedPlaybackQueueResourceManagement =
5151
PreparedPlaybackQueueResourceManagement(
5252
fakePlaybackPreparerProvider,
53-
FakePlaybackQueueConfiguration()
53+
FakePlaybackQueueConfiguration(maxQueueSize = 0)
5454
)
5555
val playbackBootstrapper = ManagedPlaylistPlayer(
5656
PlaylistVolumeManager(1.0f),
@@ -77,17 +77,19 @@ class `When Playback Is Resumed` {
7777
fun before() {
7878
val (fakePlaybackPreparerProvider, nowPlayingRepository, playbackEngine) = mut
7979

80+
val deferredResume = DeferredPromise(Unit)
81+
8082
fakePlaybackPreparerProvider.preparationSourceBeingProvided { serviceFile, deferredPreparedPlayableFile ->
8183
val playbackHandler = deferredPreparedPlayableFile.resolve()
8284
if (serviceFile == ServiceFile("1"))
8385
playbackHandler.setCurrentPosition(450)
8486

85-
if (serviceFile == ServiceFile("2"))
87+
if (serviceFile == ServiceFile("2")) {
8688
preparedAt = deferredPreparedPlayableFile.preparedAt
89+
deferredResume.resolve()
90+
}
8791
}
8892

89-
val deferredResume = DeferredPromise(Unit)
90-
9193
val promisedCollectedFiles = Promise {
9294
val collectedFiles = mutableListOf<PositionedPlayingFile?>()
9395
playbackEngine.setOnPlayingFileChanged { _, f ->
@@ -112,8 +114,6 @@ class `When Playback Is Resumed` {
112114

113115
playbackEngine.resume().toExpiringFuture().get()
114116

115-
deferredResume.resolve()
116-
117117
positionedFiles = promisedCollectedFiles.toExpiringFuture().get()
118118

119119
nowPlaying = nowPlayingRepository.promiseNowPlaying(LibraryId(libraryId)).toExpiringFuture().get()
@@ -163,6 +163,11 @@ class `When Playback Is Resumed` {
163163
).isEqualTo(Duration.ZERO)
164164
}
165165

166+
@Test
167+
fun `then the observed playlist position is correct`() {
168+
assertThat(positionedFiles?.last()?.playlistPosition).isEqualTo(1)
169+
}
170+
166171
@Test
167172
fun `then the first skipped file is only observed once`() {
168173
assertThat(positionedFiles?.map { it?.asPositionedFile() })

0 commit comments

Comments
 (0)