From dc43b26dc025d354e87feef31cb68cde41ac84ba Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Mon, 24 Apr 2023 12:17:43 +0200 Subject: [PATCH 01/11] timerstates fixed --- .../studeez/screens/session/SessionScreen.kt | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt index 451f705..0559291 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt @@ -35,8 +35,6 @@ import be.ugent.sel.studeez.resources import kotlinx.coroutines.delay import kotlin.time.Duration.Companion.seconds -var timerEnd = false - @Composable fun SessionScreen( open: (String) -> Unit, @@ -46,17 +44,7 @@ fun SessionScreen( val context = LocalContext.current val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) val mediaplayer = MediaPlayer.create(context, uri) - mediaplayer.setOnCompletionListener { - if (!mediaplayer.isPlaying) { - mediaplayer.stop() - } - if (timerEnd) { - mediaplayer.release() - } - } - mediaplayer.setOnPreparedListener { - mediaplayer.start() - } + mediaplayer.isLooping = false Column( modifier = Modifier.padding(10.dp) @@ -71,6 +59,7 @@ fun SessionScreen( ) { TextButton( onClick = { + mediaplayer.stop() mediaplayer.release() open(StudeezDestinations.HOME_SCREEN) // Vanaf hier ook naar report gaan als "end session" knop word ingedrukt @@ -102,12 +91,7 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me } if (viewModel.getTimer().hasCurrentCountdownEnded() && !viewModel.getTimer().hasEnded()) { - mediaplayer.prepare() - } - - if (!timerEnd && viewModel.getTimer().hasEnded()) { - mediaplayer.prepare() - timerEnd = true // Placeholder, vanaf hier moet het report opgestart worden en de sessie afgesloten + mediaplayer.start() } val hms = viewModel.getTimer().getHoursMinutesSeconds() From e20e972b88d9d778953ee4df6b00ac4cf81e7d7a Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Mon, 24 Apr 2023 19:52:36 +0200 Subject: [PATCH 02/11] localdatetime version --- .idea/misc.xml | 2 +- .../sel/studeez/activities/MainActivity.kt | 13 ++++++ .../timer_functional/FunctionalTimer.kt | 2 +- .../local/models/timer_functional/Time.kt | 4 ++ .../studeez/screens/session/SessionScreen.kt | 45 +++++++++++++++++++ 5 files changed, 64 insertions(+), 2 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 704c883..bdd9278 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,7 @@ - + diff --git a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt index 318fe7a..6829e7f 100644 --- a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt +++ b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt @@ -1,6 +1,7 @@ package be.ugent.sel.studeez.activities import android.os.Bundle +import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize @@ -11,6 +12,8 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import be.ugent.sel.studeez.StudeezApp +import be.ugent.sel.studeez.screens.session.SessionTest +import be.ugent.sel.studeez.screens.session.test import be.ugent.sel.studeez.ui.theme.StudeezTheme import dagger.hilt.android.AndroidEntryPoint @@ -30,6 +33,16 @@ class MainActivity : ComponentActivity() { } } } + + override fun onStop() { + test() + super.onStop() + } + + override fun onStart() { + SessionTest.updateTimer() + super.onStart() + } } @Composable diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt index dae27c6..bb7423e 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt @@ -1,7 +1,7 @@ package be.ugent.sel.studeez.data.local.models.timer_functional abstract class FunctionalTimer(initialValue: Int) { - val time: Time = Time(initialValue) + var time: Time = Time(initialValue) var view: StudyState = StudyState.FOCUS fun getHoursMinutesSeconds(): HoursMinutesSeconds { diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt index ec7702d..83be75d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt @@ -4,6 +4,10 @@ class Time(initialTime: Int) { var time = initialTime + fun min(i: Int) { + time -= i + } + fun minOne() { time-- } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt index 0559291..dee4f12 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt @@ -3,6 +3,7 @@ package be.ugent.sel.studeez.screens.session import android.media.MediaPlayer import android.media.RingtoneManager import android.net.Uri +import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.Box @@ -31,10 +32,20 @@ import androidx.hilt.navigation.compose.hiltViewModel import be.ugent.sel.studeez.R import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer.StudyState +import be.ugent.sel.studeez.data.local.models.timer_functional.Time import be.ugent.sel.studeez.resources import kotlinx.coroutines.delay +import java.time.Duration +import java.time.LocalDateTime +import java.time.ZoneId +import java.util.* +import kotlin.properties.Delegates +import kotlin.time.Duration.Companion.hours +import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds +var start: LocalDateTime = Calendar.getInstance().time.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() + @Composable fun SessionScreen( open: (String) -> Unit, @@ -46,6 +57,8 @@ fun SessionScreen( val mediaplayer = MediaPlayer.create(context, uri) mediaplayer.isLooping = false + SessionTest.setNewViewModel(viewModel = viewModel) + Column( modifier = Modifier.padding(10.dp) ) { @@ -81,6 +94,11 @@ fun SessionScreen( } } +private operator fun Time.minus(time: Time): Time { + return Time(this.time - time.time) + +} + @Composable private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: MediaPlayer) { var tikker by remember { mutableStateOf(false) } @@ -146,6 +164,33 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me } } } +} + +fun test() { + start = Calendar.getInstance().time.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() +} + +object SessionTest { + lateinit var viewModel: SessionViewModel + private var isSession: Boolean = false + + fun setNewViewModel(viewModel: SessionViewModel) { + isSession = true + this.viewModel = viewModel + } + + fun updateTimer() { + if (isSession) { + val end = Calendar.getInstance().time.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() + + val duration = Duration.between(start, end) + + val hours = duration.toHours() + val minutes = duration.toMinutes() % 60 + val seconds = duration.seconds % 60 + viewModel.getTimer().time.min((hours + minutes + seconds).toInt()) + } + } } \ No newline at end of file From ea4e7a4790e43751c75d0ae0ad9a67f234d6db74 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Mon, 24 Apr 2023 21:35:48 +0200 Subject: [PATCH 03/11] timer can run when invisible (but no sound) --- .../sel/studeez/activities/MainActivity.kt | 17 +++++++--- .../local/models/timer_functional/Time.kt | 4 --- .../studeez/screens/session/SessionScreen.kt | 32 ++++++------------- 3 files changed, 21 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt index 6829e7f..734908b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt +++ b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt @@ -1,7 +1,6 @@ package be.ugent.sel.studeez.activities import android.os.Bundle -import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize @@ -11,11 +10,15 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.lifecycle.lifecycleScope import be.ugent.sel.studeez.StudeezApp -import be.ugent.sel.studeez.screens.session.SessionTest -import be.ugent.sel.studeez.screens.session.test +import be.ugent.sel.studeez.screens.session.InvisibleSessionManager import be.ugent.sel.studeez.ui.theme.StudeezTheme import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch + +var onTimerInvisible: Job? = null @AndroidEntryPoint class MainActivity : ComponentActivity() { @@ -34,13 +37,17 @@ class MainActivity : ComponentActivity() { } } + + override fun onStop() { - test() + onTimerInvisible = lifecycleScope.launch { + InvisibleSessionManager.updateTimer() + } super.onStop() } override fun onStart() { - SessionTest.updateTimer() + onTimerInvisible?.cancel() super.onStart() } } diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt index 83be75d..ec7702d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt @@ -4,10 +4,6 @@ class Time(initialTime: Int) { var time = initialTime - fun min(i: Int) { - time -= i - } - fun minOne() { time-- } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt index dee4f12..48cf209 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt @@ -3,7 +3,6 @@ package be.ugent.sel.studeez.screens.session import android.media.MediaPlayer import android.media.RingtoneManager import android.net.Uri -import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.Box @@ -35,17 +34,11 @@ import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer.S import be.ugent.sel.studeez.data.local.models.timer_functional.Time import be.ugent.sel.studeez.resources import kotlinx.coroutines.delay -import java.time.Duration import java.time.LocalDateTime import java.time.ZoneId import java.util.* -import kotlin.properties.Delegates -import kotlin.time.Duration.Companion.hours -import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds -var start: LocalDateTime = Calendar.getInstance().time.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() - @Composable fun SessionScreen( open: (String) -> Unit, @@ -57,7 +50,7 @@ fun SessionScreen( val mediaplayer = MediaPlayer.create(context, uri) mediaplayer.isLooping = false - SessionTest.setNewViewModel(viewModel = viewModel) + InvisibleSessionManager.setNewViewModel(viewModel = viewModel) Column( modifier = Modifier.padding(10.dp) @@ -75,6 +68,7 @@ fun SessionScreen( mediaplayer.stop() mediaplayer.release() open(StudeezDestinations.HOME_SCREEN) + InvisibleSessionManager.isSession = false // Vanaf hier ook naar report gaan als "end session" knop word ingedrukt }, modifier = Modifier @@ -166,29 +160,21 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me } } -fun test() { - start = Calendar.getInstance().time.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() -} - -object SessionTest { +object InvisibleSessionManager { lateinit var viewModel: SessionViewModel - private var isSession: Boolean = false + var isSession: Boolean = false fun setNewViewModel(viewModel: SessionViewModel) { isSession = true this.viewModel = viewModel } - fun updateTimer() { + suspend fun updateTimer() { if (isSession) { - val end = Calendar.getInstance().time.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() - - val duration = Duration.between(start, end) - - val hours = duration.toHours() - val minutes = duration.toMinutes() % 60 - val seconds = duration.seconds % 60 - viewModel.getTimer().time.min((hours + minutes + seconds).toInt()) + while (true) { + delay(1.seconds) + viewModel.getTimer().tick() + } } } From addfb7e12650c3bf02ebe09e502b811ea926a561 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Tue, 25 Apr 2023 08:44:24 +0200 Subject: [PATCH 04/11] temporary solution to notification when app is in background --- .../sel/studeez/activities/MainActivity.kt | 20 ++++++++++++++++--- .../studeez/screens/session/SessionScreen.kt | 15 +++++--------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt index 734908b..96868f1 100644 --- a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt +++ b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt @@ -1,5 +1,8 @@ package be.ugent.sel.studeez.activities +import android.media.MediaPlayer +import android.media.RingtoneManager +import android.net.Uri import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -22,7 +25,13 @@ var onTimerInvisible: Job? = null @AndroidEntryPoint class MainActivity : ComponentActivity() { + + private var mediaPlayer: MediaPlayer? = null override fun onCreate(savedInstanceState: Bundle?) { + val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) + mediaPlayer = MediaPlayer.create(this, uri) + mediaPlayer?.isLooping = false + super.onCreate(savedInstanceState) setContent { StudeezTheme { @@ -37,19 +46,24 @@ class MainActivity : ComponentActivity() { } } - - override fun onStop() { onTimerInvisible = lifecycleScope.launch { - InvisibleSessionManager.updateTimer() + InvisibleSessionManager.updateTimer(mediaPlayer) } super.onStop() } override fun onStart() { + mediaPlayer?.stop() onTimerInvisible?.cancel() super.onStart() } + + override fun onDestroy() { + mediaPlayer?.stop() + mediaPlayer?.release() + super.onDestroy() + } } @Composable diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt index 48cf209..9f009f4 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt @@ -31,12 +31,8 @@ import androidx.hilt.navigation.compose.hiltViewModel import be.ugent.sel.studeez.R import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer.StudyState -import be.ugent.sel.studeez.data.local.models.timer_functional.Time import be.ugent.sel.studeez.resources import kotlinx.coroutines.delay -import java.time.LocalDateTime -import java.time.ZoneId -import java.util.* import kotlin.time.Duration.Companion.seconds @Composable @@ -50,6 +46,7 @@ fun SessionScreen( val mediaplayer = MediaPlayer.create(context, uri) mediaplayer.isLooping = false + // evt mediaplayer meegeven vanaf hier als reserve oplossing InvisibleSessionManager.setNewViewModel(viewModel = viewModel) Column( @@ -88,11 +85,6 @@ fun SessionScreen( } } -private operator fun Time.minus(time: Time): Time { - return Time(this.time - time.time) - -} - @Composable private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: MediaPlayer) { var tikker by remember { mutableStateOf(false) } @@ -169,11 +161,14 @@ object InvisibleSessionManager { this.viewModel = viewModel } - suspend fun updateTimer() { + suspend fun updateTimer(mediaPlayer: MediaPlayer?) { if (isSession) { while (true) { delay(1.seconds) viewModel.getTimer().tick() + if (viewModel.getTimer().hasCurrentCountdownEnded() && !viewModel.getTimer().hasEnded()) { + mediaPlayer?.start() + } } } } From 9c105f96a97fe33cab50af12d235142eb326b418 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Tue, 25 Apr 2023 09:37:50 +0200 Subject: [PATCH 05/11] mediaplayer from SessionScreen.kt instead of MainActivity.kt --- .../ugent/sel/studeez/activities/MainActivity.kt | 2 +- .../sel/studeez/screens/session/SessionScreen.kt | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt index 96868f1..02656bd 100644 --- a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt +++ b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt @@ -48,7 +48,7 @@ class MainActivity : ComponentActivity() { override fun onStop() { onTimerInvisible = lifecycleScope.launch { - InvisibleSessionManager.updateTimer(mediaPlayer) + InvisibleSessionManager.updateTimer() } super.onStop() } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt index 9f009f4..7b0ad3c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt @@ -47,7 +47,7 @@ fun SessionScreen( mediaplayer.isLooping = false // evt mediaplayer meegeven vanaf hier als reserve oplossing - InvisibleSessionManager.setNewViewModel(viewModel = viewModel) + InvisibleSessionManager.setParameters(viewModel = viewModel, mediaplayer = mediaplayer) Column( modifier = Modifier.padding(10.dp) @@ -153,25 +153,25 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me } object InvisibleSessionManager { - lateinit var viewModel: SessionViewModel + private lateinit var viewModel: SessionViewModel + private lateinit var mediaplayer: MediaPlayer var isSession: Boolean = false - fun setNewViewModel(viewModel: SessionViewModel) { + fun setParameters(viewModel: SessionViewModel, mediaplayer: MediaPlayer) { isSession = true this.viewModel = viewModel + this.mediaplayer = mediaplayer } - suspend fun updateTimer(mediaPlayer: MediaPlayer?) { + suspend fun updateTimer() { if (isSession) { while (true) { delay(1.seconds) viewModel.getTimer().tick() if (viewModel.getTimer().hasCurrentCountdownEnded() && !viewModel.getTimer().hasEnded()) { - mediaPlayer?.start() + mediaplayer.start() } } } } - - -} \ No newline at end of file +} From d5f3962afe86d5acb741e3e4442d95c8eb693202 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Tue, 25 Apr 2023 15:46:13 +0200 Subject: [PATCH 06/11] tests added --- .idea/inspectionProfiles/Project_Default.xml | 1 + app/build.gradle | 4 + .../studeez/screens/session/SessionScreen.kt | 1 - .../InvisibleSessionManagerTest.kt | 83 +++++++++++++++++++ gradle.properties | 2 + 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 53a1745..cd54531 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -42,5 +42,6 @@ \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index bca9a30..6489d31 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,6 +66,7 @@ dependencies { implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" implementation 'androidx.compose.material:material:1.2.0' + debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version" // ViewModel @@ -97,6 +98,9 @@ dependencies { testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' + // Coroutine testing + testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4' + // Mocking testImplementation 'org.mockito.kotlin:mockito-kotlin:3.2.0' diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt index 7b0ad3c..ac2d225 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt @@ -46,7 +46,6 @@ fun SessionScreen( val mediaplayer = MediaPlayer.create(context, uri) mediaplayer.isLooping = false - // evt mediaplayer meegeven vanaf hier als reserve oplossing InvisibleSessionManager.setParameters(viewModel = viewModel, mediaplayer = mediaplayer) Column( diff --git a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt new file mode 100644 index 0000000..5649f46 --- /dev/null +++ b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt @@ -0,0 +1,83 @@ +package be.ugent.sel.studeez.timer_functional + +import android.media.MediaPlayer +import be.ugent.sel.studeez.data.SelectedTimerState +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer +import be.ugent.sel.studeez.screens.session.InvisibleSessionManager +import be.ugent.sel.studeez.screens.session.SessionViewModel +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.advanceTimeBy +import kotlinx.coroutines.test.runTest +import org.junit.Assert +import org.junit.Test +import org.mockito.kotlin.mock + +@ExperimentalCoroutinesApi +class InvisibleSessionManagerTest { + private var timerState: SelectedTimerState = SelectedTimerState() + private lateinit var viewModel: SessionViewModel + private val mediaPlayer = mock() + + @Test + fun InvisibleEndlessTimerTest() = runTest { + timerState.selectedTimer = FunctionalEndlessTimer() + viewModel = SessionViewModel(timerState, mock()) + InvisibleSessionManager.setParameters(viewModel, mediaPlayer) + + val test = launch { + InvisibleSessionManager.updateTimer() + } + + Assert.assertEquals(viewModel.getTimer().time.time, 0) + advanceTimeBy(1_000) // Start tikker + advanceTimeBy(10_000_000) + Assert.assertEquals(viewModel.getTimer().time.time, 10000) + + test.cancel() + return@runTest + } + + @Test + fun InvisiblePomodoroTimerTest() = runTest { + val studyTime = 10 + val breakTime = 5 + val repeats = 1 + timerState.selectedTimer = FunctionalPomodoroTimer(studyTime, breakTime, repeats) + viewModel = SessionViewModel(timerState, mock()) + InvisibleSessionManager.setParameters(viewModel, mediaPlayer) + + val test = launch { + InvisibleSessionManager.updateTimer() + } + + Assert.assertEquals(viewModel.getTimer().time.time, 10) + advanceTimeBy(1_000) // start tikker + + advanceTimeBy(9_000) + Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.FOCUS) // Tijdens het focussen + + advanceTimeBy(1_000) + Assert.assertEquals(viewModel.getTimer().time.time, 0) // Focussen gedaan + + advanceTimeBy(4_000) + Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.BREAK) // Tijdens pauze + + advanceTimeBy(1_000) + Assert.assertEquals(viewModel.getTimer().time.time, 0) // Pauze gedaan + + advanceTimeBy(9_000) + Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.FOCUS_REMAINING) // Tijdens 2e focus + + advanceTimeBy(1_000) + Assert.assertEquals(viewModel.getTimer().time.time, 0) // 2e focus gedaan + + advanceTimeBy(4_000) + Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.DONE) // Done + + test.cancel() + return@runTest + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 3c5031e..edf11ef 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,8 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +org.gradle.daemon=true +org.gradle.parallel=true # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects From f46063eba1f660f4bf5af1f43714abb60eea8baa Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Tue, 25 Apr 2023 20:58:14 +0200 Subject: [PATCH 07/11] isSession vervangend door null waaarden --- .../session/InvisibleSessionManager.kt | 34 +++++++++++++++++++ .../studeez/screens/session/SessionScreen.kt | 31 ++--------------- app/src/main/res/values/strings.xml | 1 + 3 files changed, 37 insertions(+), 29 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt new file mode 100644 index 0000000..c6def28 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt @@ -0,0 +1,34 @@ +package be.ugent.sel.studeez.screens.session + +import android.media.MediaPlayer +import kotlinx.coroutines.delay +import javax.inject.Singleton +import kotlin.time.Duration.Companion.seconds + +@Singleton +object InvisibleSessionManager { + private var viewModel: SessionViewModel? = null + private var mediaplayer: MediaPlayer? = null + + fun setParameters(viewModel: SessionViewModel, mediaplayer: MediaPlayer) { + this.viewModel = viewModel + this.mediaplayer = mediaplayer + } + + suspend fun updateTimer() { + if (viewModel != null) { + while (true) { + delay(1.seconds) + viewModel!!.getTimer().tick() + if (viewModel!!.getTimer().hasCurrentCountdownEnded() && !viewModel!!.getTimer().hasEnded()) { + mediaplayer?.start() + } + } + } + } + + fun removeParameters() { + viewModel = null + mediaplayer = null + } +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt index 3a32b37..4f9ada5 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt @@ -35,7 +35,6 @@ import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer.StudyState import be.ugent.sel.studeez.resources import kotlinx.coroutines.delay -import javax.inject.Singleton import kotlin.time.Duration.Companion.seconds data class SessionActions( @@ -99,7 +98,7 @@ fun SessionScreen( TextButton( onClick = { sessionActions.releaseMediaPlayer - + InvisibleSessionManager.removeParameters() open(StudeezDestinations.HOME_SCREEN) // Vanaf hier ook naar report gaan als "end session" knop word ingedrukt }, @@ -109,7 +108,7 @@ fun SessionScreen( .background(Color.Transparent) ) { Text( - text = "End session", + text = resources().getString(R.string.end_session), color = Color.Red, fontWeight = FontWeight.Bold, fontSize = 18.sp, @@ -190,32 +189,6 @@ private fun Timer( } } - -@Singleton -object InvisibleSessionManager { - private lateinit var viewModel: SessionViewModel - private lateinit var mediaplayer: MediaPlayer - var isSession: Boolean = false - - fun setParameters(viewModel: SessionViewModel, mediaplayer: MediaPlayer) { - isSession = true - this.viewModel = viewModel - this.mediaplayer = mediaplayer - } - - suspend fun updateTimer() { - if (isSession) { - while (true) { - delay(1.seconds) - viewModel.getTimer().tick() - if (viewModel.getTimer().hasCurrentCountdownEnded() && !viewModel.getTimer().hasEnded()) { - mediaplayer.start() - } - } - } - } -} - @Preview @Composable fun TimerPreview() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 39abda6..03900b3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -44,6 +44,7 @@ Sessions + End session Profile From 04f61c751634fbc228f950e909831b209b05fce7 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Wed, 26 Apr 2023 11:00:06 +0200 Subject: [PATCH 08/11] Added test for CustomTimer when app isn't visible --- .../InvisibleSessionManagerTest.kt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt index 5649f46..fe0d1c2 100644 --- a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt +++ b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt @@ -2,6 +2,7 @@ package be.ugent.sel.studeez.timer_functional import android.media.MediaPlayer import be.ugent.sel.studeez.data.SelectedTimerState +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer @@ -80,4 +81,25 @@ class InvisibleSessionManagerTest { test.cancel() return@runTest } + + @Test + fun InvisibleCustomTimerTest() = runTest { + timerState.selectedTimer = FunctionalCustomTimer(5) + viewModel = SessionViewModel(timerState, mock()) + InvisibleSessionManager.setParameters(viewModel, mediaPlayer) + + val test = launch { + InvisibleSessionManager.updateTimer() + } + + Assert.assertEquals(viewModel.getTimer().time.time, 5) + advanceTimeBy(1_000) // Start tikker + advanceTimeBy(4_000) + Assert.assertEquals(viewModel.getTimer().time.time, 1) + advanceTimeBy(1_000) + Assert.assertEquals(viewModel.getTimer().time.time, 0) + + test.cancel() + return@runTest + } } \ No newline at end of file From e421430f0bb9442b2507722af1739d51f9ae201f Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Fri, 28 Apr 2023 14:42:37 +0200 Subject: [PATCH 09/11] mediaplayer in AbstractSessionScreen + InvisibleSessionManagerTest.kt fixed --- .../timer_functional/FunctionalCustomTimer.kt | 6 ---- .../FunctionalPomodoroTimer.kt | 10 ++----- .../timer_functional/FunctionalTimer.kt | 3 -- .../session/InvisibleSessionManager.kt | 5 +++- .../studeez/screens/session/SessionRoute.kt | 7 ++--- .../sessionScreens/AbstractSessionScreen.kt | 4 +++ .../sessionScreens/BreakSessionScreen.kt | 15 +++++++++- .../sessionScreens/CustomSessionScreen.kt | 14 ++++++++- .../sessionScreens/EndlessSessionScreen.kt | 2 ++ .../sessionScreens/GetSessionScreen.kt | 7 +++-- .../InvisibleSessionManagerTest.kt | 30 ++++++++----------- 11 files changed, 59 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt index 0d1c4f5..94871ee 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt @@ -5,12 +5,6 @@ class FunctionalCustomTimer(studyTime: Int) : FunctionalTimer(studyTime) { override fun tick() { if (!hasEnded()) { time.minOne() - } else { - mediaPlayer?.setOnCompletionListener { - mediaPlayer!!.release() - mediaPlayer = null - } - mediaPlayer?.start() } } diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt index 8189559..6dac7c6 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt @@ -10,14 +10,10 @@ class FunctionalPomodoroTimer( override fun tick() { if (hasEnded()) { - mediaPlayer?.setOnCompletionListener { - mediaPlayer!!.release() - mediaPlayer = null - } - mediaPlayer?.start() return - } else if (hasCurrentCountdownEnded()) { - mediaPlayer?.start() + } + + if (hasCurrentCountdownEnded()) { if (isInBreak) { breaksRemaining-- time.time = studyTime diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt index daec359..2d904d8 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt @@ -1,10 +1,7 @@ package be.ugent.sel.studeez.data.local.models.timer_functional -import android.media.MediaPlayer - abstract class FunctionalTimer(initialValue: Int) { val time: Time = Time(initialValue) - var mediaPlayer: MediaPlayer? = null fun getHoursMinutesSeconds(): HoursMinutesSeconds { return time.getAsHMS() diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt index 4c43d13..68fe703 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt @@ -1,5 +1,6 @@ package be.ugent.sel.studeez.screens.session +import android.media.MediaPlayer import kotlinx.coroutines.delay import javax.inject.Singleton import kotlin.time.Duration.Companion.seconds @@ -7,8 +8,9 @@ import kotlin.time.Duration.Companion.seconds @Singleton object InvisibleSessionManager { private var viewModel: SessionViewModel? = null + private var mediaPlayer: MediaPlayer? = null - fun setParameters(viewModel: SessionViewModel) { + fun setParameters(viewModel: SessionViewModel, mediaplayer: MediaPlayer) { this.viewModel = viewModel } @@ -17,6 +19,7 @@ object InvisibleSessionManager { while (true) { delay(1.seconds) viewModel!!.getTimer().tick() + } } } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionRoute.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionRoute.kt index d13c6c1..680212d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionRoute.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionRoute.kt @@ -38,13 +38,12 @@ fun SessionRoute( val mediaplayer = MediaPlayer.create(context, uri) mediaplayer.isLooping = false - viewModel.getTimer().mediaPlayer = mediaplayer - InvisibleSessionManager.setParameters( - viewModel = viewModel + viewModel = viewModel, + mediaplayer = mediaplayer ) - val sessionScreen: AbstractSessionScreen = viewModel.getTimer().accept(GetSessionScreen()) + val sessionScreen: AbstractSessionScreen = viewModel.getTimer().accept(GetSessionScreen(mediaplayer)) sessionScreen( open = open, diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/AbstractSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/AbstractSessionScreen.kt index 0804abf..f268edb 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/AbstractSessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/AbstractSessionScreen.kt @@ -73,6 +73,7 @@ abstract class AbstractSessionScreen { LaunchedEffect(tikker) { delay(1.seconds) sessionActions.getTimer().tick() + callMediaPlayer() tikker = !tikker } @@ -122,6 +123,8 @@ abstract class AbstractSessionScreen { @Composable abstract fun motivationString(): String + abstract fun callMediaPlayer() + } @Preview @@ -130,6 +133,7 @@ fun TimerPreview() { val sessionScreen = object : AbstractSessionScreen() { @Composable override fun motivationString(): String = "Test" + override fun callMediaPlayer() {} } sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {})) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/BreakSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/BreakSessionScreen.kt index edc8475..34927bc 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/BreakSessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/BreakSessionScreen.kt @@ -1,5 +1,6 @@ package be.ugent.sel.studeez.screens.session.sessionScreens +import android.media.MediaPlayer import androidx.compose.runtime.Composable import be.ugent.sel.studeez.R import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer @@ -7,7 +8,8 @@ import be.ugent.sel.studeez.resources import be.ugent.sel.studeez.R.string as AppText class BreakSessionScreen( - private val funPomoDoroTimer: FunctionalPomodoroTimer + private val funPomoDoroTimer: FunctionalPomodoroTimer, + private var mediaplayer: MediaPlayer? ): AbstractSessionScreen() { @Composable @@ -27,4 +29,15 @@ class BreakSessionScreen( ) } + override fun callMediaPlayer() { + if (funPomoDoroTimer.hasEnded()) { + mediaplayer?.setOnCompletionListener { + mediaplayer!!.release() + mediaplayer = null + } + mediaplayer?.start() + } else if (funPomoDoroTimer.hasCurrentCountdownEnded()) { + mediaplayer?.start() + } + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/CustomSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/CustomSessionScreen.kt index 36ee492..e998645 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/CustomSessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/CustomSessionScreen.kt @@ -1,5 +1,6 @@ package be.ugent.sel.studeez.screens.session.sessionScreens +import android.media.MediaPlayer import androidx.compose.runtime.Composable import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer import be.ugent.sel.studeez.resources @@ -7,7 +8,8 @@ import be.ugent.sel.studeez.R.string as AppText class CustomSessionScreen( - private val functionalTimer: FunctionalCustomTimer + private val functionalTimer: FunctionalCustomTimer, + private var mediaplayer: MediaPlayer? ): AbstractSessionScreen() { @Composable @@ -18,4 +20,14 @@ class CustomSessionScreen( return resources().getString(AppText.state_focus) } + override fun callMediaPlayer() { + if (functionalTimer.hasEnded()) { + mediaplayer?.setOnCompletionListener { + mediaplayer!!.release() + mediaplayer = null + } + mediaplayer?.start() + } + } + } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/EndlessSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/EndlessSessionScreen.kt index fc46c9d..be67cff 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/EndlessSessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/EndlessSessionScreen.kt @@ -11,4 +11,6 @@ class EndlessSessionScreen : AbstractSessionScreen() { override fun motivationString(): String { return resources().getString(AppText.state_focus) } + + override fun callMediaPlayer() {} } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt index e378661..98b2d5e 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt @@ -1,17 +1,18 @@ package be.ugent.sel.studeez.screens.session.sessionScreens +import android.media.MediaPlayer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimerVisitor -class GetSessionScreen : FunctionalTimerVisitor { +class GetSessionScreen(private val mediaplayer: MediaPlayer?) : FunctionalTimerVisitor { override fun visitFunctionalCustomTimer(functionalCustomTimer: FunctionalCustomTimer): AbstractSessionScreen = - CustomSessionScreen(functionalCustomTimer) + CustomSessionScreen(functionalCustomTimer, mediaplayer) override fun visitFunctionalEndlessTimer(functionalEndlessTimer: FunctionalEndlessTimer): AbstractSessionScreen = EndlessSessionScreen() override fun visitFunctionalBreakTimer(functionalPomodoroTimer: FunctionalPomodoroTimer): AbstractSessionScreen = - BreakSessionScreen(functionalPomodoroTimer) + BreakSessionScreen(functionalPomodoroTimer, mediaplayer) } \ No newline at end of file diff --git a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt index fe0d1c2..60740d9 100644 --- a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt +++ b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt @@ -5,7 +5,6 @@ import be.ugent.sel.studeez.data.SelectedTimerState import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer -import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer import be.ugent.sel.studeez.screens.session.InvisibleSessionManager import be.ugent.sel.studeez.screens.session.SessionViewModel import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -20,7 +19,7 @@ import org.mockito.kotlin.mock class InvisibleSessionManagerTest { private var timerState: SelectedTimerState = SelectedTimerState() private lateinit var viewModel: SessionViewModel - private val mediaPlayer = mock() + private var mediaPlayer: MediaPlayer = mock() @Test fun InvisibleEndlessTimerTest() = runTest { @@ -58,25 +57,20 @@ class InvisibleSessionManagerTest { advanceTimeBy(1_000) // start tikker advanceTimeBy(9_000) - Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.FOCUS) // Tijdens het focussen + Assert.assertEquals(viewModel.getTimer().time.time, 1) + // focus, 9 sec, 1 sec nog - advanceTimeBy(1_000) - Assert.assertEquals(viewModel.getTimer().time.time, 0) // Focussen gedaan + advanceTimeBy(2_000) + Assert.assertEquals(viewModel.getTimer().time.time, 4) + // pauze, 11 sec bezig, 4 seconden nog pauze - advanceTimeBy(4_000) - Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.BREAK) // Tijdens pauze + advanceTimeBy(5_000) + Assert.assertEquals(viewModel.getTimer().time.time, 9) + // 2e focus, 16 sec, 9 sec in 2e focus nog - advanceTimeBy(1_000) - Assert.assertEquals(viewModel.getTimer().time.time, 0) // Pauze gedaan - - advanceTimeBy(9_000) - Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.FOCUS_REMAINING) // Tijdens 2e focus - - advanceTimeBy(1_000) - Assert.assertEquals(viewModel.getTimer().time.time, 0) // 2e focus gedaan - - advanceTimeBy(4_000) - Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.DONE) // Done + advanceTimeBy(13_000) + Assert.assertTrue(viewModel.getTimer().hasEnded()) + // Done test.cancel() return@runTest From 8eb199757ce5a857a2d13d56bb971fa0cfba5385 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Fri, 28 Apr 2023 15:30:57 +0200 Subject: [PATCH 10/11] InvisibleSessionManager.kt fixed --- .../screens/session/InvisibleSessionManager.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt index 68fe703..9051fa8 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt @@ -8,18 +8,21 @@ import kotlin.time.Duration.Companion.seconds @Singleton object InvisibleSessionManager { private var viewModel: SessionViewModel? = null - private var mediaPlayer: MediaPlayer? = null + private lateinit var mediaPlayer: MediaPlayer fun setParameters(viewModel: SessionViewModel, mediaplayer: MediaPlayer) { this.viewModel = viewModel + this.mediaPlayer = mediaplayer } suspend fun updateTimer() { - if (viewModel != null) { - while (true) { + viewModel?.let { + while (!it.getTimer().hasEnded()) { delay(1.seconds) - viewModel!!.getTimer().tick() - + it.getTimer().tick() + if (it.getTimer().hasCurrentCountdownEnded()) { + mediaPlayer.start() + } } } } From 2ca7d062f30d84ef3ef481f62737f619ce6c5221 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Fri, 28 Apr 2023 19:02:10 +0200 Subject: [PATCH 11/11] mediaplayer null safe listeners --- .../session/sessionScreens/BreakSessionScreen.kt | 10 ++++++---- .../session/sessionScreens/CustomSessionScreen.kt | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/BreakSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/BreakSessionScreen.kt index 34927bc..8fa45ff 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/BreakSessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/BreakSessionScreen.kt @@ -31,11 +31,13 @@ class BreakSessionScreen( override fun callMediaPlayer() { if (funPomoDoroTimer.hasEnded()) { - mediaplayer?.setOnCompletionListener { - mediaplayer!!.release() - mediaplayer = null + mediaplayer?.let { it: MediaPlayer -> + it.setOnCompletionListener { + it.release() + mediaplayer = null + } + it.start() } - mediaplayer?.start() } else if (funPomoDoroTimer.hasCurrentCountdownEnded()) { mediaplayer?.start() } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/CustomSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/CustomSessionScreen.kt index e998645..7fc60bc 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/CustomSessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/CustomSessionScreen.kt @@ -22,11 +22,13 @@ class CustomSessionScreen( override fun callMediaPlayer() { if (functionalTimer.hasEnded()) { - mediaplayer?.setOnCompletionListener { - mediaplayer!!.release() - mediaplayer = null + mediaplayer?.let { it: MediaPlayer -> + it.setOnCompletionListener { + it.release() + mediaplayer = null + } + it.start() } - mediaplayer?.start() } }