mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-15 02:36:12 -04:00
Fix auto-resume after CAP pause
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
package eu.darken.capod.common
|
||||
|
||||
import android.media.AudioManager
|
||||
import android.os.SystemClock
|
||||
import io.mockk.Runs
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.unmockkStatic
|
||||
import io.mockk.verify
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import testhelpers.BaseTest
|
||||
|
||||
class MediaControlTest : BaseTest() {
|
||||
|
||||
private lateinit var audioManager: AudioManager
|
||||
private lateinit var mediaControl: MediaControl
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
mockkStatic(SystemClock::class)
|
||||
every { SystemClock.elapsedRealtime() } returns 1_000L
|
||||
every { SystemClock.uptimeMillis() } returns 1_000L
|
||||
audioManager = mockk(relaxed = true)
|
||||
every { audioManager.dispatchMediaKeyEvent(any()) } just Runs
|
||||
mediaControl = MediaControl(audioManager)
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun teardown() {
|
||||
unmockkStatic(SystemClock::class)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `sendPlay ignores stale active state after cap pause`() = runTest {
|
||||
every { audioManager.isMusicActive } returns true
|
||||
|
||||
mediaControl.sendPause()
|
||||
assertTrue(mediaControl.wasRecentlyPausedByCap)
|
||||
clearMocks(audioManager, answers = false, recordedCalls = true)
|
||||
|
||||
mediaControl.sendPlay()
|
||||
assertFalse(mediaControl.wasRecentlyPausedByCap)
|
||||
|
||||
verify(exactly = 2) { audioManager.dispatchMediaKeyEvent(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `sendPlayPause resumes after cap pause even when audio manager still reports active`() = runTest {
|
||||
every { audioManager.isMusicActive } returns true
|
||||
|
||||
mediaControl.sendPause()
|
||||
assertTrue(mediaControl.wasRecentlyPausedByCap)
|
||||
clearMocks(audioManager, answers = false, recordedCalls = true)
|
||||
|
||||
mediaControl.sendPlayPause()
|
||||
assertFalse(mediaControl.wasRecentlyPausedByCap)
|
||||
|
||||
verify(exactly = 2) { audioManager.dispatchMediaKeyEvent(any()) }
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@ import io.mockk.MockKAnnotations
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkObject
|
||||
import io.mockk.unmockkObject
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import testhelpers.BaseTest
|
||||
@@ -62,6 +64,11 @@ abstract class BaseBlePodsTest : BaseTest() {
|
||||
every { SystemClockWrap.elapsedRealtimeNanos } returns 1000L
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun teardown() {
|
||||
unmockkObject(SystemClockWrap)
|
||||
}
|
||||
|
||||
internal suspend inline fun <reified T : BlePodSnapshot?> create(
|
||||
hex: String,
|
||||
address: String = "77:49:4C:D8:25:0C",
|
||||
@@ -79,4 +86,4 @@ abstract class BaseBlePodsTest : BaseTest() {
|
||||
|
||||
block.invoke(factory.create(result) as T)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,24 @@ class PlayPauseLogicTest : BaseTest() {
|
||||
decision.shouldPause shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `one in to both in - should play if recently paused by cap`() {
|
||||
val previous = EarDetectionState.fromDualPod(left = true, right = false)
|
||||
val current = EarDetectionState.fromDualPod(left = true, right = true)
|
||||
|
||||
val decision = playPause.evaluatePlayPauseAction(
|
||||
previous = previous,
|
||||
current = current,
|
||||
onePodMode = false,
|
||||
isCurrentlyPlaying = true,
|
||||
wasRecentlyPausedByUs = true,
|
||||
)
|
||||
|
||||
decision.shouldPlay shouldBe true
|
||||
decision.shouldPause shouldBe false
|
||||
decision.usedRecentCapPauseOverride shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `none in to one in - no action (need both)`() {
|
||||
val previous = EarDetectionState.fromDualPod(left = false, right = false)
|
||||
@@ -288,6 +306,24 @@ class PlayPauseLogicTest : BaseTest() {
|
||||
decision.shouldPause shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `one in to both in - should play if recently paused by cap`() {
|
||||
val previous = EarDetectionState.fromDualPod(left = true, right = false)
|
||||
val current = EarDetectionState.fromDualPod(left = true, right = true)
|
||||
|
||||
val decision = playPause.evaluatePlayPauseAction(
|
||||
previous = previous,
|
||||
current = current,
|
||||
onePodMode = true,
|
||||
isCurrentlyPlaying = true,
|
||||
wasRecentlyPausedByUs = true,
|
||||
)
|
||||
|
||||
decision.shouldPlay shouldBe true
|
||||
decision.shouldPause shouldBe false
|
||||
decision.usedRecentCapPauseOverride shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `both in to one in - should pause if playing`() {
|
||||
val previous = EarDetectionState.fromDualPod(left = true, right = true)
|
||||
|
||||
Reference in New Issue
Block a user