add external modification check

This commit is contained in:
qimiko committed 2024-01-12 16:46:36 -07:00
1 parent de48c6ecd6
commit 50d062149e
4 files changed
+45 -14

No files matched your search

@@ -38,6 +38,7 @@ import com.geode.launcher.ui.theme.Theme
import com.geode.launcher.ui.theme.Typography import com.geode.launcher.ui.theme.Typography
import com.geode.launcher.utils.LaunchUtils import com.geode.launcher.utils.LaunchUtils
import com.geode.launcher.utils.PreferenceUtils import com.geode.launcher.utils.PreferenceUtils
import com.geode.launcher.utils.ReleaseManager
import com.geode.launcher.utils.useCountdownTimer import com.geode.launcher.utils.useCountdownTimer
import java.net.ConnectException import java.net.ConnectException
import java.net.UnknownHostException import java.net.UnknownHostException
@@ -152,6 +153,14 @@ fun UpdateCard(releaseViewModel: ReleaseViewModel, modifier: Modifier = Modifier
val message = when (state.exception) { val message = when (state.exception) {
is UnknownHostException, is ConnectException -> is UnknownHostException, is ConnectException ->
stringResource(R.string.release_fetch_no_internet) stringResource(R.string.release_fetch_no_internet)
is ReleaseManager.UpdateException -> {
when (state.exception.reason) {
ReleaseManager.UpdateException.Reason.EXTERNAL_FILE_IN_USE -> stringResource(
R.string.release_fetch_manual_check_required
)
else -> state.exception.message
}
}
else -> state.exception.message else -> state.exception.message
} }
@@ -97,6 +97,7 @@ class PreferenceUtils(private val sharedPreferences: SharedPreferences) {
CURRENT_VERSION_TIMESTAMP, CURRENT_VERSION_TIMESTAMP,
THEME, THEME,
BLACK_BACKGROUND, BLACK_BACKGROUND,
CURRENT_RELEASE_MODIFIED,
} }
private fun defaultValueForBooleanKey(key: Key): Boolean { private fun defaultValueForBooleanKey(key: Key): Boolean {
@@ -116,6 +117,7 @@ class PreferenceUtils(private val sharedPreferences: SharedPreferences) {
Key.CURRENT_VERSION_TIMESTAMP -> "PreferenceCurrentVersionDescriptor" Key.CURRENT_VERSION_TIMESTAMP -> "PreferenceCurrentVersionDescriptor"
Key.THEME -> "PreferenceTheme" Key.THEME -> "PreferenceTheme"
Key.BLACK_BACKGROUND -> "PreferenceBlackBackground" Key.BLACK_BACKGROUND -> "PreferenceBlackBackground"
Key.CURRENT_RELEASE_MODIFIED -> "PreferenceReleaseModified"
} }
} }
@@ -9,7 +9,6 @@ import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
@@ -58,6 +57,15 @@ class ReleaseManager private constructor(
data class Finished(val hasUpdated: Boolean = false) : ReleaseManagerState() data class Finished(val hasUpdated: Boolean = false) : ReleaseManagerState()
} }
class UpdateException(reason: Reason? = null, cause: Throwable? = null) : Exception(reason?.name, cause) {
enum class Reason {
EXTERNAL_FILE_IN_USE
}
var reason: Reason? = reason
private set
}
private var updateJob: Job? = null private var updateJob: Job? = null
private val _uiState = MutableStateFlow<ReleaseManagerState>(ReleaseManagerState.Finished()) private val _uiState = MutableStateFlow<ReleaseManagerState>(ReleaseManagerState.Finished())
@@ -157,23 +165,34 @@ class ReleaseManager private constructor(
return return
} }
// check if the file was externally modified
val fileLastModified = sharedPreferences.getLong(PreferenceUtils.Key.CURRENT_RELEASE_MODIFIED)
if (fileLastModified != 0L && fileLastModified != geodeFile.lastModified()) {
sendError(UpdateException(UpdateException.Reason.EXTERNAL_FILE_IN_USE))
return
}
performUpdate(release) performUpdate(release)
} }
private suspend fun updatePreferences(release: Release) { private fun updatePreferences(release: Release) {
coroutineScope { val sharedPreferences = PreferenceUtils.get(applicationContext)
val sharedPreferences = PreferenceUtils.get(applicationContext)
sharedPreferences.setString( sharedPreferences.setString(
PreferenceUtils.Key.CURRENT_VERSION_TAG, PreferenceUtils.Key.CURRENT_VERSION_TAG,
release.getDescription() release.getDescription()
) )
sharedPreferences.setLong( sharedPreferences.setLong(
PreferenceUtils.Key.CURRENT_VERSION_TIMESTAMP, PreferenceUtils.Key.CURRENT_VERSION_TIMESTAMP,
release.getDescriptor() release.getDescriptor()
) )
}
val outputFile = getGeodeOutputPath()
sharedPreferences.setLong(
PreferenceUtils.Key.CURRENT_RELEASE_MODIFIED,
outputFile.lastModified()
)
} }
private fun getGeodeOutputPath(): File { private fun getGeodeOutputPath(): File {
+2 -1
View File
@@ -1,5 +1,5 @@
<resources> <resources>
<string name="app_name">Geode</string> <string name="app_name" translatable="false">Geode</string>
<string name="no_activity_found">No activity found for this action.</string> <string name="no_activity_found">No activity found for this action.</string>
<!-- MainActivity strings --> <!-- MainActivity strings -->
@@ -30,6 +30,7 @@
<string name="release_fetch_cancelled">Update cancelled.</string> <string name="release_fetch_cancelled">Update cancelled.</string>
<string name="release_fetch_button_retry">Retry</string> <string name="release_fetch_button_retry">Retry</string>
<string name="release_fetch_button_cancel">Cancel</string> <string name="release_fetch_button_cancel">Cancel</string>
<string name="release_fetch_manual_check_required">Externally managed library in use, please manually check for updates if you want to overwrite it.</string>
<!-- GeometryDashActivity strings --> <!-- GeometryDashActivity strings -->
<string name="message_box_cancel">Cancel</string> <string name="message_box_cancel">Cancel</string>