Keep annoy unblock counter during reboot

This commit is contained in:
Jonas Lochmann 2022-03-07 01:00:00 +01:00
parent d72b6801dd
commit d4bfa37caf
No known key found for this signature in database
GPG key ID: 8B8C9AEE10FA5B36
6 changed files with 1323 additions and 6 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2021 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -274,4 +274,10 @@ object DatabaseMigrations {
database.execSQL("ALTER TABLE category ADD COLUMN block_notification_delay INTEGER NOT NULL DEFAULT 0")
}
}
val MIGRATE_TO_V39 = object: Migration(38, 39) {
override fun migrate(database: SupportSQLiteDatabase) {
// nothing to do, there was just a new config item type added
}
}
}

View file

@ -51,7 +51,7 @@ import java.util.concurrent.TimeUnit
UserLimitLoginCategory::class,
CategoryNetworkId::class,
ChildTask::class
], version = 38)
], version = 39)
abstract class RoomDatabase: RoomDatabase(), io.timelimit.android.data.Database {
companion object {
private val lock = Object()
@ -123,7 +123,8 @@ abstract class RoomDatabase: RoomDatabase(), io.timelimit.android.data.Database
DatabaseMigrations.MIGRATE_TO_V35,
DatabaseMigrations.MIGRATE_TO_V36,
DatabaseMigrations.MIGRATE_TO_V37,
DatabaseMigrations.MIGRATE_TO_V38
DatabaseMigrations.MIGRATE_TO_V38,
DatabaseMigrations.MIGRATE_TO_V39
)
.setQueryExecutor(Threads.database)
.addCallback(object: Callback() {

View file

@ -327,4 +327,7 @@ abstract class ConfigDao {
fun getServerApiLevelSync() = getValueOfKeySync(ConfigurationItemType.ServerApiLevel).let { it?.toInt() ?: 0 }
fun getServerApiLevelLive() = getValueOfKeyAsync(ConfigurationItemType.ServerApiLevel).map { it?.toInt() ?: 0 }
fun setServerApiLevelSync(serverApiLevel: Int) { updateValueSync(ConfigurationItemType.ServerApiLevel, serverApiLevel.toString()) }
fun getAnnoyManualUnblockCounter() = getValueOfKeySync(ConfigurationItemType.AnnoyManualUnblockCounter).let { it?.toInt() ?: 0 }
fun setAnoyManualUnblockCounterSync(counter: Int) { updateValueSync(ConfigurationItemType.AnnoyManualUnblockCounter, counter.toString()) }
}

View file

@ -99,7 +99,8 @@ enum class ConfigurationItemType {
EnableUpdates,
UpdateStatus,
CustomOrganizationName,
ServerApiLevel
ServerApiLevel,
AnnoyManualUnblockCounter,
}
object ConfigurationItemTypeUtil {
@ -126,6 +127,7 @@ object ConfigurationItemTypeUtil {
private const val UPDATE_STATUS = 22
private const val CUSTOM_ORGANIZATION_NAME = 23
private const val SERVER_API_LEVEL = 24
private const val ANNOY_MANUAL_UNBLOCK_COUNTER = 25
val TYPES = listOf(
ConfigurationItemType.OwnDeviceId,
@ -150,7 +152,8 @@ object ConfigurationItemTypeUtil {
ConfigurationItemType.EnableUpdates,
ConfigurationItemType.UpdateStatus,
ConfigurationItemType.CustomOrganizationName,
ConfigurationItemType.ServerApiLevel
ConfigurationItemType.ServerApiLevel,
ConfigurationItemType.AnnoyManualUnblockCounter
)
fun serialize(value: ConfigurationItemType) = when(value) {
@ -177,6 +180,7 @@ object ConfigurationItemTypeUtil {
ConfigurationItemType.UpdateStatus -> UPDATE_STATUS
ConfigurationItemType.CustomOrganizationName -> CUSTOM_ORGANIZATION_NAME
ConfigurationItemType.ServerApiLevel -> SERVER_API_LEVEL
ConfigurationItemType.AnnoyManualUnblockCounter -> ANNOY_MANUAL_UNBLOCK_COUNTER
}
fun parse(value: Int) = when(value) {
@ -203,6 +207,7 @@ object ConfigurationItemTypeUtil {
UPDATE_STATUS -> ConfigurationItemType.UpdateStatus
CUSTOM_ORGANIZATION_NAME -> ConfigurationItemType.CustomOrganizationName
SERVER_API_LEVEL -> ConfigurationItemType.ServerApiLevel
ANNOY_MANUAL_UNBLOCK_COUNTER -> ConfigurationItemType.AnnoyManualUnblockCounter
else -> throw IllegalArgumentException()
}
}

View file

@ -15,11 +15,13 @@
*/
package io.timelimit.android.logic
import android.os.Build
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import io.timelimit.android.BuildConfig
import io.timelimit.android.async.Threads
import io.timelimit.android.coroutines.executeAndWait
import io.timelimit.android.coroutines.runAsync
import io.timelimit.android.integration.platform.ProtectionLevel
import io.timelimit.android.livedata.*
@ -27,6 +29,7 @@ class AnnoyLogic (val appLogic: AppLogic) {
// config
companion object {
private const val ENABLE = !BuildConfig.storeCompilant
private const val LOG_TAG = "AnnoyLogic"
private const val TEMP_UNBLOCK_DURATION = 1000 * 45L
private const val TEMP_UNBLOCK_PARENT_DURATION = 1000 * 60 * 10L
@ -87,6 +90,7 @@ class AnnoyLogic (val appLogic: AppLogic) {
nextManualUnblockTimestamp = now + manualUnblockDelay(manualUnblockCounter)
enableTempDisabled(TEMP_UNBLOCK_DURATION)
saveManualUnblockCounterAsync()
}
// input: trigger temp unblock by parents (event)
@ -95,8 +99,10 @@ class AnnoyLogic (val appLogic: AppLogic) {
nextManualUnblockTimestamp = now()
enableTempDisabled(TEMP_UNBLOCK_PARENT_DURATION)
saveManualUnblockCounterAsync()
}
// helper functions
private fun enableTempDisabled(duration: Long) {
annoyTempDisabled.value = true
@ -104,4 +110,75 @@ class AnnoyLogic (val appLogic: AppLogic) {
Threads.mainThreadHandler.postDelayed(annoyTempDisabledSetFalse, duration)
isManipulated.observeForever(resetTempDisabledObserver)
}
// state saving and restoring
private fun saveManualUnblockCounterAsync() {
Threads.mainThreadHandler.removeCallbacks(saveZeroUnblockCounterRunnable)
Threads.database.execute {
try {
appLogic.database.config().setAnoyManualUnblockCounterSync(manualUnblockCounter)
} catch (ex: Exception) {
if (BuildConfig.DEBUG) {
Log.w(LOG_TAG, "could not save unblock counter value", ex)
}
}
}
eventuallyScheduleResetOfStoredCounter()
}
private fun eventuallyScheduleResetOfStoredCounter() {
if (manualUnblockCounter > 0) {
val now = now()
val resetTimestamp = nextManualUnblockTimestamp + manualUnblockDelay(manualUnblockCounter)
val resetDelay = resetTimestamp - now
if (resetDelay > 0) {
if (BuildConfig.DEBUG) {
Log.d(LOG_TAG, "scheduled counter reset in ${resetDelay/1000} seconds")
}
Threads.mainThreadHandler.postDelayed(saveZeroUnblockCounterRunnable, resetDelay)
}
}
}
private val saveZeroUnblockCounterRunnable = Runnable {
Threads.database.execute {
if (BuildConfig.DEBUG) {
Log.d(LOG_TAG, "reset counter now")
}
try {
appLogic.database.config().setAnoyManualUnblockCounterSync(0)
} catch (ex: Exception) {
if (BuildConfig.DEBUG) {
Log.w(LOG_TAG, "could not reset saved counter value", ex)
}
}
}
}
init {
runAsync {
try {
val counter = Threads.database.executeAndWait {
appLogic.database.config().getAnnoyManualUnblockCounter()
}
val now = now()
if (counter > 0) {
manualUnblockCounter = counter
nextManualUnblockTimestamp = now + manualUnblockDelay(manualUnblockCounter)
eventuallyScheduleResetOfStoredCounter()
}
} catch (ex: Exception) {
if (BuildConfig.DEBUG) {
Log.w(LOG_TAG, "could not load saved counter", ex)
}
}
}
}
}