diff --git a/app/src/main/java/io/timelimit/android/data/RoomDatabase.kt b/app/src/main/java/io/timelimit/android/data/RoomDatabase.kt index 974eb2b..7250969 100644 --- a/app/src/main/java/io/timelimit/android/data/RoomDatabase.kt +++ b/app/src/main/java/io/timelimit/android/data/RoomDatabase.kt @@ -21,6 +21,7 @@ import androidx.room.Database import androidx.room.InvalidationTracker import androidx.room.Room import androidx.room.RoomDatabase +import io.timelimit.android.async.Threads import io.timelimit.android.data.dao.DerivedDataDao import io.timelimit.android.data.invalidation.Observer import io.timelimit.android.data.invalidation.Table @@ -28,6 +29,7 @@ import io.timelimit.android.data.invalidation.TableUtil import io.timelimit.android.data.model.* import java.lang.ref.WeakReference import java.util.concurrent.CountDownLatch +import java.util.concurrent.TimeUnit @Database(entities = [ User::class, @@ -113,6 +115,7 @@ abstract class RoomDatabase: RoomDatabase(), io.timelimit.android.data.Database DatabaseMigrations.MIGRATE_TO_V30, DatabaseMigrations.MIGRATE_TO_V31 ) + .setQueryExecutor(Threads.database) .build() } } @@ -157,21 +160,21 @@ abstract class RoomDatabase: RoomDatabase(), io.timelimit.android.data.Database val latch = CountDownLatch(1) try { - queryExecutor.execute { latch.await() } + queryExecutor.execute { latch.await(5, TimeUnit.SECONDS) } // without requesting a async refresh, no sync refresh will happen invalidationTracker.refreshVersionsAsync() invalidationTracker.refreshVersionsSync() - - openHelper.readableDatabase.beginTransaction() - try { - synchronized(transactionCommitListeners) { transactionCommitListeners.toList() }.forEach { it() } - } finally { - openHelper.readableDatabase.endTransaction() - } } finally { latch.countDown() } + + openHelper.readableDatabase.beginTransaction() + try { + synchronized(transactionCommitListeners) { transactionCommitListeners.toList() }.forEach { it() } + } finally { + openHelper.readableDatabase.endTransaction() + } } } diff --git a/app/src/main/java/io/timelimit/android/data/backup/DatabaseBackup.kt b/app/src/main/java/io/timelimit/android/data/backup/DatabaseBackup.kt index 9f64fa3..ae317a3 100644 --- a/app/src/main/java/io/timelimit/android/data/backup/DatabaseBackup.kt +++ b/app/src/main/java/io/timelimit/android/data/backup/DatabaseBackup.kt @@ -1,5 +1,5 @@ /* - * TimeLimit Copyright 2019 Jonas Lochmann + * TimeLimit Copyright 2019 - 2020 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 @@ -19,6 +19,7 @@ import android.content.Context import android.util.Log import androidx.core.util.AtomicFile import io.timelimit.android.BuildConfig +import io.timelimit.android.async.Threads import io.timelimit.android.coroutines.executeAndWait import io.timelimit.android.data.RoomDatabase import kotlinx.coroutines.runBlocking @@ -81,8 +82,9 @@ class DatabaseBackup(private val context: Context) { try { jsonFile.openRead().use { inputStream -> - - DatabaseBackupLowlevel.restoreFromBackupJson(database, inputStream) + Threads.database.executeAndWait { + DatabaseBackupLowlevel.restoreFromBackupJson(database, inputStream) + } } if (BuildConfig.DEBUG) { diff --git a/app/src/main/java/io/timelimit/android/data/cache/multi/DataCacheLiveData.kt b/app/src/main/java/io/timelimit/android/data/cache/multi/DataCacheLiveData.kt index a30b9ea..36cf251 100644 --- a/app/src/main/java/io/timelimit/android/data/cache/multi/DataCacheLiveData.kt +++ b/app/src/main/java/io/timelimit/android/data/cache/multi/DataCacheLiveData.kt @@ -43,7 +43,9 @@ fun DataCacheUserInterface.openLive(key: K, executor: Executor): Li override fun onInactive() { super.onInactive() - cache.close(key, listener) + executor.execute { + cache.close(key, listener) + } } } } diff --git a/app/src/main/java/io/timelimit/android/data/cache/single/SingleItemDataCacheLiveData.kt b/app/src/main/java/io/timelimit/android/data/cache/single/SingleItemDataCacheLiveData.kt index 93c157c..5b554bb 100644 --- a/app/src/main/java/io/timelimit/android/data/cache/single/SingleItemDataCacheLiveData.kt +++ b/app/src/main/java/io/timelimit/android/data/cache/single/SingleItemDataCacheLiveData.kt @@ -43,7 +43,9 @@ fun SingleItemDataCacheUserInterface.openLive(executor: Executor): LiveDa override fun onInactive() { super.onInactive() - cache.close(listener) + executor.execute { + cache.close(listener) + } } } } diff --git a/app/src/main/java/io/timelimit/android/logic/SuspendAppsLogic.kt b/app/src/main/java/io/timelimit/android/logic/SuspendAppsLogic.kt index dd1a91f..a3b9dbd 100644 --- a/app/src/main/java/io/timelimit/android/logic/SuspendAppsLogic.kt +++ b/app/src/main/java/io/timelimit/android/logic/SuspendAppsLogic.kt @@ -41,6 +41,8 @@ class SuspendAppsLogic(private val appLogic: AppLogic): Observer { private val pendingSync = AtomicBoolean(true) private val executor = Executors.newSingleThreadExecutor() private var lastSuspendedApps: List? = null + private val userAndDeviceRelatedDataLive = appLogic.database.derivedDataDao().getUserAndDeviceRelatedDataLive() + private var didLoadUserAndDeviceRelatedData = false private val backgroundRunnable = Runnable { while (pendingSync.getAndSet(false)) { @@ -67,7 +69,7 @@ class SuspendAppsLogic(private val appLogic: AppLogic): Observer { appLogic.database.registerWeakObserver(arrayOf(Table.App), WeakReference(this)) appLogic.platformIntegration.getBatteryStatusLive().observeForever { batteryStatus = it; triggerUpdate() } appLogic.realTimeLogic.registerTimeModificationListener { triggerUpdate() } - appLogic.database.derivedDataDao().getUserAndDeviceRelatedDataLive().observeForever { triggerUpdate() } + userAndDeviceRelatedDataLive.observeForever { didLoadUserAndDeviceRelatedData = true; triggerUpdate() } } override fun onInvalidated(tables: Set) { @@ -75,7 +77,9 @@ class SuspendAppsLogic(private val appLogic: AppLogic): Observer { } private fun updateBlockingSync() { - val userAndDeviceRelatedData = appLogic.database.derivedDataDao().getUserAndDeviceRelatedDataSync() + if (!didLoadUserAndDeviceRelatedData) return + + val userAndDeviceRelatedData = userAndDeviceRelatedDataLive.value val isRestrictedUser = userAndDeviceRelatedData?.userRelatedData?.user?.type == UserType.Child val enableBlockingAtSystemLevel = userAndDeviceRelatedData?.deviceRelatedData?.isExperimentalFlagSetSync(ExperimentalFlags.SYSTEM_LEVEL_BLOCKING) ?: false