Add visibility for the user during app restoring
When the app is restoring the button's text will be constantly updated until the app is restored. Test: manual Bug: 304255818 Change-Id: Id5da0923e5f9f3e45889e10c017a3f3dc3f8bd95
This commit is contained in:
@@ -3945,6 +3945,14 @@
|
|||||||
<string name="archive">Archive</string>
|
<string name="archive">Archive</string>
|
||||||
<!-- Manage applications, text label for button to restore an application. Restoring means installing the archived app. -->
|
<!-- Manage applications, text label for button to restore an application. Restoring means installing the archived app. -->
|
||||||
<string name="restore">Restore</string>
|
<string name="restore">Restore</string>
|
||||||
|
<!-- Manage applications, text label for button while the application is restoring. -->
|
||||||
|
<string name="restoring_step_one">Restoring</string>
|
||||||
|
<!-- Manage applications, text label for button while the application is restoring. -->
|
||||||
|
<string name="restoring_step_two">Restoring.</string>
|
||||||
|
<!-- Manage applications, text label for button while the application is restoring. -->
|
||||||
|
<string name="restoring_step_three">Restoring..</string>
|
||||||
|
<!-- Manage applications, text label for button while the application is restoring. -->
|
||||||
|
<string name="restoring_step_four">Restoring...</string>
|
||||||
<!-- Manage applications, individual application info screen,label under Storage heading. The total storage space taken up by this app. -->
|
<!-- Manage applications, individual application info screen,label under Storage heading. The total storage space taken up by this app. -->
|
||||||
<string name="total_size_label">Total</string>
|
<string name="total_size_label">Total</string>
|
||||||
<!-- Manage applications, individual application info screen, label under Storage heading. The amount of space taken up by the application itself (for example, the java compield files and things like that) -->
|
<!-- Manage applications, individual application info screen, label under Storage heading. The amount of space taken up by the application itself (for example, the java compield files and things like that) -->
|
||||||
|
@@ -27,9 +27,18 @@ import android.widget.Toast
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.CloudDownload
|
import androidx.compose.material.icons.outlined.CloudDownload
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
import com.android.settingslib.spa.widget.button.ActionButton
|
import com.android.settingslib.spa.widget.button.ActionButton
|
||||||
import com.android.settingslib.spaprivileged.framework.compose.DisposableBroadcastReceiverAsUser
|
import com.android.settingslib.spaprivileged.framework.compose.DisposableBroadcastReceiverAsUser
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.isActive
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class AppRestoreButton(packageInfoPresenter: PackageInfoPresenter) {
|
class AppRestoreButton(packageInfoPresenter: PackageInfoPresenter) {
|
||||||
private companion object {
|
private companion object {
|
||||||
@@ -43,6 +52,16 @@ class AppRestoreButton(packageInfoPresenter: PackageInfoPresenter) {
|
|||||||
private val packageName = packageInfoPresenter.packageName
|
private val packageName = packageInfoPresenter.packageName
|
||||||
private val userHandle = UserHandle.of(packageInfoPresenter.userId)
|
private val userHandle = UserHandle.of(packageInfoPresenter.userId)
|
||||||
private var broadcastReceiverIsCreated = false
|
private var broadcastReceiverIsCreated = false
|
||||||
|
private lateinit var coroutineScope: CoroutineScope
|
||||||
|
private lateinit var updateButtonTextJob: Job
|
||||||
|
private val buttonTexts = intArrayOf(
|
||||||
|
R.string.restore,
|
||||||
|
R.string.restoring_step_one,
|
||||||
|
R.string.restoring_step_two,
|
||||||
|
R.string.restoring_step_three,
|
||||||
|
R.string.restoring_step_four,
|
||||||
|
)
|
||||||
|
private var buttonTextIndexStateFlow = MutableStateFlow(0)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun getActionButton(app: ApplicationInfo): ActionButton {
|
fun getActionButton(app: ApplicationInfo): ActionButton {
|
||||||
@@ -55,10 +74,17 @@ class AppRestoreButton(packageInfoPresenter: PackageInfoPresenter) {
|
|||||||
}
|
}
|
||||||
broadcastReceiverIsCreated = true
|
broadcastReceiverIsCreated = true
|
||||||
}
|
}
|
||||||
|
coroutineScope = rememberCoroutineScope()
|
||||||
|
if (app.isArchived && ::updateButtonTextJob.isInitialized && !updateButtonTextJob.isActive) {
|
||||||
|
buttonTextIndexStateFlow.value = 0
|
||||||
|
}
|
||||||
return ActionButton(
|
return ActionButton(
|
||||||
text = context.getString(R.string.restore),
|
text = context.getString(
|
||||||
|
buttonTexts[
|
||||||
|
buttonTextIndexStateFlow.asStateFlow().collectAsStateWithLifecycle(0).value]
|
||||||
|
),
|
||||||
imageVector = Icons.Outlined.CloudDownload,
|
imageVector = Icons.Outlined.CloudDownload,
|
||||||
enabled = app.isArchived
|
enabled = app.isArchived && (!::updateButtonTextJob.isInitialized || !updateButtonTextJob.isActive)
|
||||||
) { onRestoreClicked(app) }
|
) { onRestoreClicked(app) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +113,18 @@ class AppRestoreButton(packageInfoPresenter: PackageInfoPresenter) {
|
|||||||
when (val unarchiveStatus =
|
when (val unarchiveStatus =
|
||||||
intent.getIntExtra(PackageInstaller.EXTRA_UNARCHIVE_STATUS, Int.MIN_VALUE)) {
|
intent.getIntExtra(PackageInstaller.EXTRA_UNARCHIVE_STATUS, Int.MIN_VALUE)) {
|
||||||
PackageInstaller.UNARCHIVAL_OK -> {
|
PackageInstaller.UNARCHIVAL_OK -> {
|
||||||
|
// updateButtonTextJob will be canceled automatically once
|
||||||
|
// AppButtonsPresenter#getActionButtons is triggered
|
||||||
|
updateButtonTextJob = coroutineScope.launch {
|
||||||
|
while (isActive) {
|
||||||
|
var index = buttonTextIndexStateFlow.value
|
||||||
|
index = (index + 1) % buttonTexts.size
|
||||||
|
// The initial state shouldn't be used here
|
||||||
|
if (index == 0) index++
|
||||||
|
buttonTextIndexStateFlow.emit(index)
|
||||||
|
delay(1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
val appLabel = userPackageManager.getApplicationLabel(app)
|
val appLabel = userPackageManager.getApplicationLabel(app)
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
context,
|
context,
|
||||||
|
Reference in New Issue
Block a user