aboutsummaryrefslogtreecommitdiff
path: root/app/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main')
-rw-r--r--app/src/main/java/invalid/lena/rsend/App.kt7
-rw-r--r--app/src/main/java/invalid/lena/rsend/MainActivity.kt50
2 files changed, 44 insertions, 13 deletions
diff --git a/app/src/main/java/invalid/lena/rsend/App.kt b/app/src/main/java/invalid/lena/rsend/App.kt
index 0251d7d..443229d 100644
--- a/app/src/main/java/invalid/lena/rsend/App.kt
+++ b/app/src/main/java/invalid/lena/rsend/App.kt
@@ -3,6 +3,7 @@ package invalid.lena.rsend
import android.app.Application
import android.app.NotificationChannel
import android.app.NotificationManager
+import kotlin.concurrent.thread
// App creates the notification channel used by the foreground sync service.
class App : Application() {
@@ -13,8 +14,10 @@ class App : Application() {
getSystemService(NotificationManager::class.java).createNotificationChannel(ch)
// Apply on every process start, including one launched by an old
// WorkManager request after an app upgrade. This retires stale unique
- // names without waiting for the dashboard to be opened.
- Scheduler.apply(this)
+ // names without waiting for the dashboard to be opened. Off the main
+ // thread: it reads the config and opens WorkManager's database, and
+ // nothing here has to finish before the first screen draws.
+ thread { Scheduler.apply(this) }
}
companion object {
diff --git a/app/src/main/java/invalid/lena/rsend/MainActivity.kt b/app/src/main/java/invalid/lena/rsend/MainActivity.kt
index 875afdf..06270ca 100644
--- a/app/src/main/java/invalid/lena/rsend/MainActivity.kt
+++ b/app/src/main/java/invalid/lena/rsend/MainActivity.kt
@@ -62,6 +62,10 @@ class MainActivity : AppCompatActivity() {
private var jobState: String = "none"
private var recoveryShown = false
+ // Settles overlapping refreshes: a resume and a finishing sync can start
+ // one each, and only the newest read may draw.
+ private var generation = 0
+
private val notifPerm =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { refresh() }
@@ -221,15 +225,11 @@ class MainActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
- Scheduler.apply(this)
refresh()
- showRecoveryNotice()
}
- private fun showRecoveryNotice() {
- if (recoveryShown) return
- val message = Config.recoveryMessage(this).trim()
- if (message.isEmpty()) return
+ private fun showRecoveryNotice(message: String) {
+ if (recoveryShown || message.isEmpty()) return
recoveryShown = true
AlertDialog.Builder(this)
.setTitle("Configuration recovered")
@@ -277,12 +277,40 @@ class MainActivity : AppCompatActivity() {
scheduleValue.text = "$sched, job $jobState"
}
+ // One read of everything the dashboard draws.
+ private data class Dashboard(
+ val cfg: Config,
+ val lastSync: String,
+ val keyExists: Boolean,
+ val recovery: String,
+ )
+
+ // Every field above comes from an app-private file, so read them on a worker
+ // thread and draw the result. Reading them during layout was the same
+ // main-thread stall the WorkManager query was moved off.
private fun refresh() {
- val cfg = Config.load(this)
+ val current = ++generation
+ thread {
+ Scheduler.apply(this)
+ val d = Dashboard(
+ cfg = Config.load(this),
+ lastSync = LastSync.get(this),
+ keyExists = Keys.exists(this),
+ recovery = Config.recoveryMessage(this).trim(),
+ )
+ runOnUiThread {
+ if (isFinishing || isDestroyed || current != generation) return@runOnUiThread
+ draw(d)
+ }
+ }
+ }
- lastSync.text = "Last sync: ${LastSync.get(this)}"
+ private fun draw(d: Dashboard) {
+ val cfg = d.cfg
- keyValue.text = if (Keys.exists(this)) "Generated, tap to view" else "Not created, tap to create"
+ lastSync.text = "Last sync: ${d.lastSync}"
+
+ keyValue.text = if (d.keyExists) "Generated, tap to view" else "Not created, tap to create"
schedule = cfg.schedule
renderSchedule(cfg.schedule)
@@ -324,6 +352,8 @@ class MainActivity : AppCompatActivity() {
}
}
}
+
+ showRecoveryNotice(d.recovery)
}
// addRow inflates one tappable list row: icon, title, subtitle, chip.
@@ -451,7 +481,6 @@ class MainActivity : AppCompatActivity() {
runOnUiThread {
if (isFinishing || isDestroyed) return@runOnUiThread
if (error == null) {
- Scheduler.apply(this)
refresh()
Toast.makeText(this, "New key generated.", Toast.LENGTH_SHORT).show()
showKey()
@@ -497,7 +526,6 @@ class MainActivity : AppCompatActivity() {
runOnUiThread {
if (isFinishing || isDestroyed) return@runOnUiThread
if (error == null) {
- Scheduler.apply(this)
refresh()
Toast.makeText(this, "Key imported.", Toast.LENGTH_SHORT).show()
showKey()