Skip to content

Commit

Permalink
fix: Use mutex for processing state validation
Browse files Browse the repository at this point in the history
Change-Id: I738e565067770fb80003b7bd0dc040e3e2fd855b
  • Loading branch information
XayahSuSuSu committed Oct 4, 2023
1 parent e8422ba commit be8fa57
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
Expand All @@ -27,6 +28,8 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import javax.inject.Inject

enum class OpType {
Expand All @@ -35,6 +38,7 @@ enum class OpType {
}

data class MediaBackupListUiState(
val mutex: Mutex,
val isLoading: Boolean,
val opType: OpType,
val timestamp: Long,
Expand All @@ -48,6 +52,7 @@ data class MediaBackupListUiState(
class MediaBackupListViewModel @Inject constructor(private val mediaDao: MediaDao) : ViewModel() {
private val _uiState = mutableStateOf(
MediaBackupListUiState(
mutex = Mutex(),
isLoading = true,
opType = OpType.LIST,
timestamp = DateUtil.getTimestamp(),
Expand Down Expand Up @@ -132,18 +137,24 @@ class MediaBackupListViewModel @Inject constructor(private val mediaDao: MediaDa
}

fun onProcessing() {
if (uiState.value.opType == OpType.LIST)
viewModelScope.launch {
withIOContext {
updateTimestamp()
setType(OpType.PROCESSING)
val uiState by uiState

viewModelScope.launch {
uiState.mutex.withLock {
if (uiState.opType == OpType.LIST) {
withIOContext {
setType(OpType.PROCESSING)

val operationLocalService = OperationLocalService(context = DataBackupApplication.application)
operationLocalService.backupMedium(uiState.value.timestamp)
operationLocalService.destroyService()
updateTimestamp()

setType(OpType.LIST)
val operationLocalService = OperationLocalService(context = DataBackupApplication.application)
operationLocalService.backupMedium(uiState.timestamp)
operationLocalService.destroyService()

setType(OpType.LIST)
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import javax.inject.Inject

data class MediaRestoreListUiState(
val mutex: Mutex,
val isLoading: Boolean,
val opType: OpType,
val timestamps: List<Long>,
Expand All @@ -37,6 +40,7 @@ data class MediaRestoreListUiState(
class MediaRestoreListViewModel @Inject constructor(private val mediaDao: MediaDao) : ViewModel() {
private val _uiState = mutableStateOf(
MediaRestoreListUiState(
mutex = Mutex(),
isLoading = false,
opType = OpType.LIST,
timestamps = listOf(),
Expand Down Expand Up @@ -85,17 +89,22 @@ class MediaRestoreListViewModel @Inject constructor(private val mediaDao: MediaD
}

fun onProcessing() {
if (uiState.value.opType == OpType.LIST)
viewModelScope.launch {
withIOContext {
setType(OpType.PROCESSING)
val uiState by uiState

val operationLocalService = OperationLocalService(context = DataBackupApplication.application)
operationLocalService.restoreMedium(uiState.value.timestamp)
operationLocalService.destroyService()
viewModelScope.launch {
uiState.mutex.withLock {
if (uiState.opType == OpType.LIST) {
withIOContext {
setType(OpType.PROCESSING)

setType(OpType.LIST)
val operationLocalService = OperationLocalService(context = DataBackupApplication.application)
operationLocalService.restoreMedium(uiState.timestamp)
operationLocalService.destroyService()

setType(OpType.LIST)
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.xayah.databackup.ui.activity.operation.page.packages.backup

import android.app.Application
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
Expand All @@ -15,6 +16,8 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import javax.inject.Inject

enum class ProcessingState {
Expand All @@ -24,6 +27,7 @@ enum class ProcessingState {
}

data class ProcessingUiState(
val mutex: Mutex,
val timestamp: Long,
var effectLaunched: Boolean,
var effectFinished: Boolean,
Expand All @@ -44,6 +48,7 @@ class ProcessingViewModel @Inject constructor(
) : ViewModel() {
private val _uiState = mutableStateOf(
ProcessingUiState(
mutex = Mutex(),
timestamp = DateUtil.getTimestamp(),
effectLaunched = false,
effectFinished = false,
Expand All @@ -56,23 +61,28 @@ class ProcessingViewModel @Inject constructor(
get() = _uiState

fun backupPackages() {
val uiState = uiState.value
if (_uiState.value.effectLaunched.not())
viewModelScope.launch {
withIOContext {
_uiState.value = uiState.copy(effectLaunched = true)
val operationLocalService = OperationLocalService(context = context)
val preparation = operationLocalService.backupPackagesPreparation()
val uiState by uiState

_uiState.value = uiState.copy(effectState = ProcessingState.Processing)
operationLocalService.backupPackages(timestamp = uiState.timestamp)
viewModelScope.launch {
uiState.mutex.withLock {
if (uiState.effectLaunched.not()) {
withIOContext {
_uiState.value = uiState.copy(effectLaunched = true)

_uiState.value = uiState.copy(effectState = ProcessingState.Waiting)
operationLocalService.backupPackagesAfterwards(preparation)
val operationLocalService = OperationLocalService(context = context)
val preparation = operationLocalService.backupPackagesPreparation()

operationLocalService.destroyService()
_uiState.value = uiState.copy(effectFinished = true)
_uiState.value = uiState.copy(effectState = ProcessingState.Processing)
operationLocalService.backupPackages(timestamp = uiState.timestamp)

_uiState.value = uiState.copy(effectState = ProcessingState.Waiting)
operationLocalService.backupPackagesAfterwards(preparation)

operationLocalService.destroyService()
_uiState.value = uiState.copy(effectFinished = true)
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import javax.inject.Inject

data class ProcessingUiState(
val mutex: Mutex,
val timestamp: Long,
var effectLaunched: Boolean,
var effectFinished: Boolean,
Expand All @@ -40,6 +43,7 @@ class ProcessingViewModel @Inject constructor(
) : ViewModel() {
private val _uiState = mutableStateOf(
ProcessingUiState(
mutex = Mutex(),
timestamp = DateUtil.getTimestamp(),
effectLaunched = false,
effectFinished = false,
Expand All @@ -53,19 +57,24 @@ class ProcessingViewModel @Inject constructor(

fun restorePackages() {
val uiState by uiState
if (uiState.effectLaunched.not())
viewModelScope.launch {
withIOContext {
_uiState.value = uiState.copy(effectLaunched = true)
val operationLocalService = OperationLocalService(context = context)
operationLocalService.restorePackagesPreparation()

_uiState.value = uiState.copy(effectState = ProcessingState.Processing)
operationLocalService.restorePackages(timestamp = uiState.timestamp)
viewModelScope.launch {
uiState.mutex.withLock {
if (uiState.effectLaunched.not()) {
withIOContext {
_uiState.value = uiState.copy(effectLaunched = true)

operationLocalService.destroyService()
_uiState.value = uiState.copy(effectFinished = true)
val operationLocalService = OperationLocalService(context = context)
operationLocalService.restorePackagesPreparation()

_uiState.value = uiState.copy(effectState = ProcessingState.Processing)
operationLocalService.restorePackages(timestamp = uiState.timestamp)

operationLocalService.destroyService()
_uiState.value = uiState.copy(effectFinished = true)
}
}
}
}
}
}

0 comments on commit be8fa57

Please sign in to comment.