diff --git a/app/src/androidTest/java/com/stevesoltys/seedvault/e2e/LargeBackupTestBase.kt b/app/src/androidTest/java/com/stevesoltys/seedvault/e2e/LargeBackupTestBase.kt index 738e19e6..ab4e1fdf 100644 --- a/app/src/androidTest/java/com/stevesoltys/seedvault/e2e/LargeBackupTestBase.kt +++ b/app/src/androidTest/java/com/stevesoltys/seedvault/e2e/LargeBackupTestBase.kt @@ -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() 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 } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 80180014..0a79268a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -101,6 +101,7 @@ diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/notification/BackupNotificationManager.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/notification/BackupNotificationManager.kt index 251bf9b7..1bd8a9b8 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/ui/notification/BackupNotificationManager.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/ui/notification/BackupNotificationManager.kt @@ -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) diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/notification/NotificationBackupObserver.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/notification/NotificationBackupObserver.kt index 49fad317..ac0fa195 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/ui/notification/NotificationBackupObserver.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/ui/notification/NotificationBackupObserver.kt @@ -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() } } } diff --git a/app/src/main/java/com/stevesoltys/seedvault/worker/BackupRequester.kt b/app/src/main/java/com/stevesoltys/seedvault/worker/BackupRequester.kt index f7a7ce95..c4dfb61a 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/worker/BackupRequester.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/worker/BackupRequester.kt @@ -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") diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f3c32247..5bf7309e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -155,6 +155,7 @@ Backup finished %1$d of %2$d apps backed up (%3$s). Tap to learn more. Backup failed + An error occurred while running the backup. Error notification Backup error