Keep screen on and hold wake lock during important parts of backup restore.

This commit is contained in:
Cody Henthorne
2025-06-12 11:56:17 -04:00
committed by Michelle Tang
parent 88f17e29aa
commit 9bde632c6d
3 changed files with 101 additions and 9 deletions

View File

@@ -8,6 +8,7 @@ package org.thoughtcrime.securesms.registrationv3.ui.restore
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.WindowManager
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.foundation.background
@@ -31,8 +32,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.filterIsInstance
@@ -89,19 +92,46 @@ class RemoteRestoreActivity : BaseActivity() {
private val contactSupportViewModel: ContactSupportViewModel by viewModels()
private lateinit var wakeLock: RemoteRestoreWakeLock
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch {
val restored = viewModel
.state
.map { it.importState }
.filterIsInstance<RemoteRestoreViewModel.ImportState.Restored>()
.firstOrNull()
wakeLock = RemoteRestoreWakeLock(this)
if (restored != null) {
startActivity(MainActivity.clearTop(this@RemoteRestoreActivity))
finish()
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
val restored = viewModel
.state
.map { it.importState }
.filterIsInstance<RemoteRestoreViewModel.ImportState.Restored>()
.firstOrNull()
if (restored != null) {
startActivity(MainActivity.clearTop(this@RemoteRestoreActivity))
finish()
}
}
}
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
viewModel
.state
.map { it.importState }
.collect {
when (it) {
RemoteRestoreViewModel.ImportState.InProgress -> {
wakeLock.acquire()
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
else -> {
wakeLock.release()
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
}
}
}
}

View File

@@ -0,0 +1,49 @@
package org.thoughtcrime.securesms.registrationv3.ui.restore
import android.os.PowerManager
import androidx.activity.ComponentActivity
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import org.thoughtcrime.securesms.util.WakeLockUtil
import kotlin.time.Duration.Companion.minutes
/**
* Holds on to and manages a wake-lock when restoring a remote backup.
*/
class RemoteRestoreWakeLock(
private val activity: ComponentActivity
) : DefaultLifecycleObserver {
companion object {
private val TIMEOUT = 10.minutes.inWholeMilliseconds
}
private var wakeLock: PowerManager.WakeLock? = null
init {
activity.lifecycle.addObserver(this)
}
fun acquire() {
synchronized(this) {
if (wakeLock?.isHeld == true) {
return
}
wakeLock = WakeLockUtil.acquire(activity, PowerManager.PARTIAL_WAKE_LOCK, TIMEOUT, "remoteRestore")
}
}
fun release() {
synchronized(this) {
if (wakeLock?.isHeld == true) {
wakeLock?.release()
wakeLock = null
}
}
}
override fun onPause(owner: LifecycleOwner) {
release()
}
}

View File

@@ -7,6 +7,7 @@ package org.thoughtcrime.securesms.registrationv3.ui.restore
import android.os.Bundle
import android.view.View
import android.view.WindowManager
import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -44,7 +45,9 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.fragment.findNavController
@@ -81,6 +84,16 @@ class RestoreViaQrFragment : ComposeFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
override fun onPause(owner: LifecycleOwner) {
requireActivity().window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
})
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) {
viewModel