Skip to content

Commit

Permalink
refactor: BasePomodoroTimer 추가 및 Timer에서 추가적인 비즈니스로직 제거
Browse files Browse the repository at this point in the history
  • Loading branch information
lee-ji-hoon committed Nov 9, 2024
1 parent 6a4f169 commit 2777d28
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 139 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.pomonyang.mohanyang.presentation.di

import com.pomonyang.mohanyang.data.repository.pomodoro.PomodoroTimerRepository
import com.pomonyang.mohanyang.presentation.service.PomodoroTimer
import com.pomonyang.mohanyang.presentation.service.focus.FocusTimer
import com.pomonyang.mohanyang.presentation.service.rest.RestTimer
Expand All @@ -15,13 +14,9 @@ internal object PomodoroModule {

@Provides
@FocusTimerType
fun provideFocusTimer(
timerRepository: PomodoroTimerRepository
): PomodoroTimer = FocusTimer(timerRepository = timerRepository)
fun provideFocusTimer(): PomodoroTimer = FocusTimer()

@Provides
@RestTimerType
fun provideRestTimer(
timerRepository: PomodoroTimerRepository
): PomodoroTimer = RestTimer(timerRepository = timerRepository)
fun provideRestTimer(): PomodoroTimer = RestTimer()
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.pomonyang.mohanyang.presentation.screen
import com.mohanyang.presentation.BuildConfig

object PomodoroConstants {
val TIMER_DELAY = if (BuildConfig.DEBUG) 10L else 1_000L
val TIMER_DELAY = if (BuildConfig.DEBUG) 100L else 1_000L
val MAX_EXCEEDED_TIME = if (BuildConfig.DEBUG) 60 else 3600
const val MAX_FOCUS_MINUTES = 60
const val MAX_REST_MINUTES = 30
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.pomonyang.mohanyang.presentation.service

import com.pomonyang.mohanyang.presentation.model.setting.PomodoroCategoryType
import com.pomonyang.mohanyang.presentation.screen.PomodoroConstants.MAX_EXCEEDED_TIME
import com.pomonyang.mohanyang.presentation.screen.PomodoroConstants.ONE_SECOND
import com.pomonyang.mohanyang.presentation.screen.PomodoroConstants.TIMER_DELAY
import java.util.*
import kotlin.concurrent.fixedRateTimer
import timber.log.Timber

internal abstract class BasePomodoroTimer : PomodoroTimer {
private var timer: Timer? = null
private var timeElapsed = 0

protected abstract fun getTagName(): String

override fun startTimer(
maxTime: Int,
eventHandler: PomodoroTimerEventHandler,
category: PomodoroCategoryType?
) {
Timber.tag(getTagName()).d("startTimer / maxTime : $maxTime")
if (timer == null) {
timeElapsed = 0
timer = fixedRateTimer(initialDelay = TIMER_DELAY, period = TIMER_DELAY) {
timeElapsed += ONE_SECOND

Timber.tag(getTagName()).d("countTime: $timeElapsed ")

eventHandler.updateTimer(
time = if (timeElapsed >= maxTime) maxTime.toString() else timeElapsed.toString(),
overtime = if (maxTime >= timeElapsed) "0" else (timeElapsed - maxTime).toString(),
category = category
)

if (timeElapsed == maxTime) {
eventHandler.onTimeEnd()
} else if (timeElapsed >= maxTime + MAX_EXCEEDED_TIME) {
eventHandler.onTimeExceeded()
stopTimer()
}
}
}
}

override fun stopTimer() {
timer?.cancel()
timer = null
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.pomonyang.mohanyang.presentation.service

import com.pomonyang.mohanyang.presentation.model.setting.PomodoroCategoryType
import com.pomonyang.mohanyang.presentation.noti.PomodoroNotificationManager

internal interface PomodoroTimer {

fun startTimer(
maxTime: Int,
eventHandler: PomodoroTimerEventHandler,
pomodoroNotificationManager: PomodoroNotificationManager,
category: PomodoroCategoryType? = null
)

fun stopTimer()
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.pomonyang.mohanyang.presentation.service

import com.pomonyang.mohanyang.presentation.model.setting.PomodoroCategoryType

internal interface PomodoroTimerEventHandler {
fun onTimeEnd()
fun onTimeExceeded()
fun updateTimer(time: String, overtime: String, category: PomodoroCategoryType?)
}
Original file line number Diff line number Diff line change
@@ -1,65 +1,9 @@
package com.pomonyang.mohanyang.presentation.service.focus

import com.pomonyang.mohanyang.data.repository.pomodoro.PomodoroTimerRepository
import com.pomonyang.mohanyang.presentation.model.setting.PomodoroCategoryType
import com.pomonyang.mohanyang.presentation.noti.PomodoroNotificationManager
import com.pomonyang.mohanyang.presentation.screen.PomodoroConstants.MAX_EXCEEDED_TIME
import com.pomonyang.mohanyang.presentation.screen.PomodoroConstants.ONE_SECOND
import com.pomonyang.mohanyang.presentation.screen.PomodoroConstants.TIMER_DELAY
import com.pomonyang.mohanyang.presentation.service.PomodoroTimer
import com.pomonyang.mohanyang.presentation.service.PomodoroTimerEventHandler
import java.util.*
import com.pomonyang.mohanyang.presentation.service.BasePomodoroTimer
import javax.inject.Inject
import kotlin.concurrent.fixedRateTimer
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import timber.log.Timber

internal class FocusTimer @Inject constructor(
private val timerRepository: PomodoroTimerRepository
) : PomodoroTimer {
internal class FocusTimer @Inject constructor() : BasePomodoroTimer() {

private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
private var timer: Timer? = null
private var timeElapsed = 0

override fun startTimer(
maxTime: Int,
eventHandler: PomodoroTimerEventHandler,
pomodoroNotificationManager: PomodoroNotificationManager,
category: PomodoroCategoryType?
) {
Timber.tag("TIMER").d("startFocus timer / maxTime : $maxTime")
if (timer == null) {
timeElapsed = 0
timer = fixedRateTimer(initialDelay = TIMER_DELAY, period = TIMER_DELAY) {
scope.launch {
timeElapsed += ONE_SECOND
timerRepository.incrementFocusedTime()

Timber.tag("TIMER").d("countFocusTime: $timeElapsed ")

pomodoroNotificationManager.updateNotification(
time = if (timeElapsed >= maxTime) maxTime.toString() else timeElapsed.toString(),
overtime = if (maxTime >= timeElapsed) "0" else (timeElapsed - maxTime).toString(),
category = category
)

if (timeElapsed >= maxTime) {
eventHandler.onTimeEnd()
} else if (timeElapsed >= maxTime + MAX_EXCEEDED_TIME) {
eventHandler.onTimeExceeded()
stopTimer()
}
}
}
}
}

override fun stopTimer() {
timer?.cancel()
timer = null
}
override fun getTagName(): String = "TIMER_FOCUS"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@ package com.pomonyang.mohanyang.presentation.service.focus

import android.app.Service
import android.content.Intent
import android.os.Build
import android.os.IBinder
import com.pomonyang.mohanyang.data.repository.pomodoro.PomodoroTimerRepository
import com.pomonyang.mohanyang.presentation.di.FocusTimerType
import com.pomonyang.mohanyang.presentation.model.setting.PomodoroCategoryType
import com.pomonyang.mohanyang.presentation.noti.PomodoroNotificationManager
import com.pomonyang.mohanyang.presentation.screen.PomodoroConstants.POMODORO_NOTIFICATION_ID
import com.pomonyang.mohanyang.presentation.service.PomodoroTimer
import com.pomonyang.mohanyang.presentation.service.PomodoroTimerEventHandler
import com.pomonyang.mohanyang.presentation.service.PomodoroTimerServiceExtras
import com.pomonyang.mohanyang.presentation.util.MnNotificationManager
import com.pomonyang.mohanyang.presentation.util.getSerializableExtraCompat
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import timber.log.Timber

@AndroidEntryPoint
Expand All @@ -27,15 +33,16 @@ internal class PomodoroFocusTimerService :
@Inject
lateinit var pomodoroNotificationManager: PomodoroNotificationManager

@Inject
lateinit var timerRepository: PomodoroTimerRepository

private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())

override fun onBind(intent: Intent?): IBinder? = null

override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
val maxTime = intent.getIntExtra(PomodoroTimerServiceExtras.INTENT_TIMER_MAX_TIME, 0)
val category = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
intent.getSerializableExtra(PomodoroTimerServiceExtras.INTENT_FOCUS_CATEGORY, PomodoroCategoryType::class.java)
} else {
intent.getSerializableExtra(PomodoroTimerServiceExtras.INTENT_FOCUS_CATEGORY) as PomodoroCategoryType
}
val category = intent.getSerializableExtraCompat<PomodoroCategoryType>(PomodoroTimerServiceExtras.INTENT_FOCUS_CATEGORY)

Timber.tag("TIMER").d("onStartCommand > ${intent.action} / maxTime: $maxTime / category $category")
when (intent.action) {
Expand All @@ -47,7 +54,6 @@ internal class PomodoroFocusTimerService :
focusTimer.startTimer(
maxTime = maxTime,
eventHandler = this,
pomodoroNotificationManager = pomodoroNotificationManager,
category = category
)
}
Expand All @@ -62,11 +68,23 @@ internal class PomodoroFocusTimerService :
}

override fun onTimeEnd() {
// pomodoroNotificationManager.notifyFocusEnd()
Timber.tag("TIMER").d("onFocusTimeEnd")
MnNotificationManager.notifyFocusEnd(context = this)
}

override fun onTimeExceeded() {
// pomodoroNotificationManager.notifyFocusExceed()
// TODO 여기 뭔가 로직이 필요하면 그때 추가
}

override fun updateTimer(time: String, overtime: String, category: PomodoroCategoryType?) {
scope.launch {
timerRepository.incrementFocusedTime()
}
pomodoroNotificationManager.updateNotification(
time = time,
overtime = overtime,
category = category
)
}

override fun stopService(name: Intent?): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@ package com.pomonyang.mohanyang.presentation.service.rest
import android.app.Service
import android.content.Intent
import android.os.IBinder
import com.pomonyang.mohanyang.data.repository.pomodoro.PomodoroTimerRepository
import com.pomonyang.mohanyang.presentation.di.RestTimerType
import com.pomonyang.mohanyang.presentation.model.setting.PomodoroCategoryType
import com.pomonyang.mohanyang.presentation.noti.PomodoroNotificationManager
import com.pomonyang.mohanyang.presentation.screen.PomodoroConstants
import com.pomonyang.mohanyang.presentation.service.PomodoroTimer
import com.pomonyang.mohanyang.presentation.service.PomodoroTimerEventHandler
import com.pomonyang.mohanyang.presentation.service.PomodoroTimerServiceExtras
import com.pomonyang.mohanyang.presentation.util.MnNotificationManager
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import timber.log.Timber

@AndroidEntryPoint
internal class PomodoroRestTimerService :
Expand All @@ -24,6 +32,11 @@ internal class PomodoroRestTimerService :
@Inject
lateinit var pomodoroNotificationManager: PomodoroNotificationManager

@Inject
lateinit var timerRepository: PomodoroTimerRepository

private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())

override fun onBind(intent: Intent?): IBinder? = null

override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
Expand All @@ -36,8 +49,7 @@ internal class PomodoroRestTimerService :
)
restTimer.startTimer(
maxTime = maxTime,
eventHandler = this,
pomodoroNotificationManager = pomodoroNotificationManager
eventHandler = this
)
}

Expand All @@ -51,11 +63,23 @@ internal class PomodoroRestTimerService :
}

override fun onTimeEnd() {
// pomodoroNotificationManager.notifyRestEnd()
Timber.tag("TIMER").d("onRestTimeEnd")
MnNotificationManager.notifyRestEnd(context = this)
}

override fun onTimeExceeded() {
// pomodoroNotificationManager.notifyRestExceed()
// TODO 여기 뭔가 로직이 필요하면 그때 추가
}

override fun updateTimer(time: String, overtime: String, category: PomodoroCategoryType?) {
scope.launch {
timerRepository.incrementRestedTime()
}
pomodoroNotificationManager.updateNotification(
time = time,
overtime = overtime,
category = category
)
}

override fun stopService(name: Intent?): Boolean {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,63 +1,9 @@
package com.pomonyang.mohanyang.presentation.service.rest

import com.pomonyang.mohanyang.data.repository.pomodoro.PomodoroTimerRepository
import com.pomonyang.mohanyang.presentation.model.setting.PomodoroCategoryType
import com.pomonyang.mohanyang.presentation.noti.PomodoroNotificationManager
import com.pomonyang.mohanyang.presentation.screen.PomodoroConstants.MAX_EXCEEDED_TIME
import com.pomonyang.mohanyang.presentation.screen.PomodoroConstants.ONE_SECOND
import com.pomonyang.mohanyang.presentation.screen.PomodoroConstants.TIMER_DELAY
import com.pomonyang.mohanyang.presentation.service.PomodoroTimer
import com.pomonyang.mohanyang.presentation.service.PomodoroTimerEventHandler
import java.util.*
import com.pomonyang.mohanyang.presentation.service.BasePomodoroTimer
import javax.inject.Inject
import kotlin.concurrent.fixedRateTimer
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import timber.log.Timber

internal class RestTimer @Inject constructor(
private val timerRepository: PomodoroTimerRepository
) : PomodoroTimer {
internal class RestTimer @Inject constructor() : BasePomodoroTimer() {

private var timer: Timer? = null
private var timeElapsed = 0
private val scope = CoroutineScope(Dispatchers.IO)

override fun startTimer(
maxTime: Int,
eventHandler: PomodoroTimerEventHandler,
pomodoroNotificationManager: PomodoroNotificationManager,
category: PomodoroCategoryType?
) {
Timber.tag("TIMER").d("startRest timer / maxTime : $maxTime")
if (timer == null) {
timeElapsed = 0
timer = fixedRateTimer(initialDelay = TIMER_DELAY, period = TIMER_DELAY) {
scope.launch {
timeElapsed += ONE_SECOND
timerRepository.incrementRestedTime()

Timber.tag("TIMER").d("countRestTime: $timeElapsed ")
pomodoroNotificationManager.updateNotification(
time = if (timeElapsed >= maxTime) maxTime.toString() else timeElapsed.toString(),
overtime = if (maxTime >= timeElapsed) "0" else (timeElapsed - maxTime).toString(),
category = null
)

if (timeElapsed >= maxTime) {
eventHandler.onTimeEnd()
} else if (timeElapsed >= maxTime + MAX_EXCEEDED_TIME) {
eventHandler.onTimeExceeded()
stopTimer()
}
}
}
}
}

override fun stopTimer() {
timer?.cancel()
timer = null
}
override fun getTagName(): String = "TIMER_REST"
}
Loading

0 comments on commit 2777d28

Please sign in to comment.