Split up success and error notification

Now, we don't do partial backups anymore. A snapshot is only done at the end and no information can make it to the backup before. Hence the old error notification with number of apps backed up didn't make sense anymore.
This commit is contained in:
Torsten Grote 2024-09-27 17:36:05 -03:00
parent b7b07d0ba1
commit 84dc13d267
No known key found for this signature in database
GPG key ID: 3E5F77D92CF891FF
6 changed files with 41 additions and 14 deletions

View file

@ -24,6 +24,7 @@ import kotlinx.coroutines.withTimeout
import org.koin.core.component.get
import java.io.ByteArrayOutputStream
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.test.fail
internal interface LargeBackupTestBase : LargeTestBase {
@ -189,7 +190,7 @@ internal interface LargeBackupTestBase : LargeTestBase {
clearMocks(spyBackupNotificationManager)
every {
spyBackupNotificationManager.onBackupFinished(any(), any(), any(), any())
spyBackupNotificationManager.onBackupSuccess(any(), any(), any())
} answers {
val success = firstArg<Boolean>()
assert(success) { "Backup failed." }
@ -197,6 +198,13 @@ internal interface LargeBackupTestBase : LargeTestBase {
callOriginal()
completed.set(true)
}
every {
spyBackupNotificationManager.onBackupError()
} answers {
callOriginal()
completed.set(true)
fail("Backup failed.")
}
return completed
}

View file

@ -101,6 +101,7 @@
<activity
android:name=".settings.SettingsActivity"
android:exported="true"
android:launchMode="singleTask"
android:permission="com.stevesoltys.seedvault.OPEN_SETTINGS"
android:windowSoftInputMode="adjustResize" />

View file

@ -185,21 +185,17 @@ internal class BackupNotificationManager(private val context: Context) {
// }
}
fun onBackupFinished(success: Boolean, numBackedUp: Int?, total: Int, size: Long) {
val titleRes =
if (success) R.string.notification_success_title else R.string.notification_failed_title
val contentText = if (numBackedUp == null) null else {
val sizeStr = Formatter.formatShortFileSize(context, size)
fun onBackupSuccess(numBackedUp: Int, total: Int, size: Long) {
val sizeStr = Formatter.formatShortFileSize(context, size)
val contentText =
context.getString(R.string.notification_success_text, numBackedUp, total, sizeStr)
}
val iconRes = if (success) R.drawable.ic_cloud_done else R.drawable.ic_cloud_error
val intent = Intent(context, SettingsActivity::class.java).apply {
if (success) action = ACTION_APP_STATUS_LIST
action = ACTION_APP_STATUS_LIST
}
val pendingIntent = PendingIntent.getActivity(context, 0, intent, FLAG_IMMUTABLE)
val notification = Builder(context, CHANNEL_ID_SUCCESS).apply {
setSmallIcon(iconRes)
setContentTitle(context.getString(titleRes))
setSmallIcon(R.drawable.ic_cloud_done)
setContentTitle(context.getString(R.string.notification_success_title))
setContentText(contentText)
setOngoing(false)
setShowWhen(true)
@ -213,8 +209,27 @@ internal class BackupNotificationManager(private val context: Context) {
nm.notify(NOTIFICATION_ID_SUCCESS, notification)
}
@SuppressLint("RestrictedApi")
fun onBackupError() {
val intent = Intent(context, SettingsActivity::class.java)
val pendingIntent = PendingIntent.getActivity(context, 0, intent, FLAG_IMMUTABLE)
val notification = Builder(context, CHANNEL_ID_ERROR).apply {
setSmallIcon(R.drawable.ic_cloud_error)
setContentTitle(context.getString(R.string.notification_failed_title))
setContentText(context.getString(R.string.notification_failed_text))
setOngoing(false)
setShowWhen(true)
setAutoCancel(true)
setContentIntent(pendingIntent)
setWhen(System.currentTimeMillis())
setProgress(0, 0, false)
priority = PRIORITY_LOW
}.build()
nm.cancel(NOTIFICATION_ID_OBSERVER)
nm.notify(NOTIFICATION_ID_ERROR, notification)
}
@SuppressLint("RestrictedApi")
fun onFixableBackupError() {
val intent = Intent(context, SettingsActivity::class.java)
val pendingIntent = PendingIntent.getActivity(context, 0, intent, FLAG_IMMUTABLE)
val actionText = context.getString(R.string.notification_error_action)

View file

@ -172,10 +172,12 @@ internal class NotificationBackupObserver(
snapshot.blobsMap[it.hexFromProto()]?.uncompressedLength?.toLong() ?: 0L
}
} else 0L
nm.onBackupFinished(success, numPackagesToReport, total, size)
if (success) {
nm.onBackupSuccess(numPackagesToReport, total, size)
// prune old backups
AppBackupPruneWorker.scheduleNow(context)
} else {
nm.onBackupError()
}
}
}

View file

@ -115,7 +115,7 @@ internal class BackupRequester(
} catch (e: RemoteException) {
Log.e(TAG, "Error during backup: ", e)
val nm: BackupNotificationManager = GlobalContext.get().get()
nm.onBackupError()
nm.onFixableBackupError()
}
return if (result == BackupManager.SUCCESS) {
Log.i(TAG, "Backup request succeeded")

View file

@ -155,6 +155,7 @@
<string name="notification_success_title">Backup finished</string>
<string name="notification_success_text">%1$d of %2$d apps backed up (%3$s). Tap to learn more.</string>
<string name="notification_failed_title">Backup failed</string>
<string name="notification_failed_text">An error occurred while running the backup.</string>
<string name="notification_error_channel_title">Error notification</string>
<string name="notification_error_title">Backup error</string>