Merge "Add visibility for the user during app restoring" into main
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 776e3f4..2b5117d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3967,6 +3967,14 @@
<string name="archive">Archive</string>
<!-- Manage applications, text label for button to restore an application. Restoring means installing the archived app. -->
<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. -->
<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) -->
diff --git a/src/com/android/settings/spa/app/appinfo/AppRestoreButton.kt b/src/com/android/settings/spa/app/appinfo/AppRestoreButton.kt
index 6596529..bf46e95 100644
--- a/src/com/android/settings/spa/app/appinfo/AppRestoreButton.kt
+++ b/src/com/android/settings/spa/app/appinfo/AppRestoreButton.kt
@@ -27,9 +27,18 @@
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.CloudDownload
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settings.R
import com.android.settingslib.spa.widget.button.ActionButton
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) {
private companion object {
@@ -43,6 +52,16 @@
private val packageName = packageInfoPresenter.packageName
private val userHandle = UserHandle.of(packageInfoPresenter.userId)
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
fun getActionButton(app: ApplicationInfo): ActionButton {
@@ -55,10 +74,17 @@
}
broadcastReceiverIsCreated = true
}
+ coroutineScope = rememberCoroutineScope()
+ if (app.isArchived && ::updateButtonTextJob.isInitialized && !updateButtonTextJob.isActive) {
+ buttonTextIndexStateFlow.value = 0
+ }
return ActionButton(
- text = context.getString(R.string.restore),
+ text = context.getString(
+ buttonTexts[
+ buttonTextIndexStateFlow.asStateFlow().collectAsStateWithLifecycle(0).value]
+ ),
imageVector = Icons.Outlined.CloudDownload,
- enabled = app.isArchived
+ enabled = app.isArchived && (!::updateButtonTextJob.isInitialized || !updateButtonTextJob.isActive)
) { onRestoreClicked(app) }
}
@@ -87,6 +113,18 @@
when (val unarchiveStatus =
intent.getIntExtra(PackageInstaller.EXTRA_UNARCHIVE_STATUS, Int.MIN_VALUE)) {
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)
Toast.makeText(
context,