From 56fbdaea18ac2b0d656380cadf6dbeb6ad0c6064 Mon Sep 17 00:00:00 2001 From: "Luis Guzman (AppDevForAll)" Date: Wed, 24 Jun 2026 16:58:23 +0000 Subject: [PATCH] fix(backup): make no-checksum/no-manifest transparency visible (import + restore) Pre-existing UX bug from the integrity PR (#37), surfaced after the #43 carve: - Import: the install_warn_no_checksum / install_warn_manifest_missing snackbar was immediately replaced by the unconditional install_msg_import_success Snackbar (Snackbar replaces, never queues) -> user never saw it. Now ONE snackbar: the warn strings (which already begin with 'Imported') become the final message when applicable. - Restore: no transparency was shown at all (it was only wired at the import gate). The restore log now leads with the no-checksum/no-manifest note, read cheaply from the identity manifest (origin=device-backup). The meaningful moment for the user. No new strings/imports; behaviour-only fix in BackupController. --- .../backup/presentation/BackupController.java | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/controller/app/src/main/java/org/iiab/controller/backup/presentation/BackupController.java b/controller/app/src/main/java/org/iiab/controller/backup/presentation/BackupController.java index 6adb56e..36d2df4 100644 --- a/controller/app/src/main/java/org/iiab/controller/backup/presentation/BackupController.java +++ b/controller/app/src/main/java/org/iiab/controller/backup/presentation/BackupController.java @@ -465,7 +465,19 @@ private void refreshRestoreButtonLogic() { btnAdvancedRestore.startProgress(); if (restoreLogPanel != null) { restoreLogPanel.setVisibility(View.VISIBLE); - if (restoreLogText != null) restoreLogText.setText(""); + if (restoreLogText != null) { + // Transparency at restore (the meaningful moment): note when the + // backup carries no integrity checksum / no manifest. + org.iiab.controller.deploy.data.RootfsManifest.Identity rid = + org.iiab.controller.deploy.data.RootfsManifest.read(backupFile.getAbsolutePath()); + if (!rid.present) { + restoreLogText.setText(fragment.getString(R.string.install_warn_manifest_missing) + "\n\n"); + } else if ("device-backup".equals(rid.origin)) { + restoreLogText.setText(fragment.getString(R.string.install_warn_no_checksum) + "\n\n"); + } else { + restoreLogText.setText(""); + } + } if (restoreLogResult != null) restoreLogResult.setText(""); } File iiabRootDir = new File(fragment.requireContext().getFilesDir(), "rootfs"); @@ -629,16 +641,6 @@ private void importBackupSafely(Uri sourceUri) { } // Soft phase: no identity manifest -> import is allowed, but warn the // user (a future version will validate silently). See docs/ROOTFS_MANIFEST.md. - if (okNoManifest && fragment.getActivity() != null) { - fragment.getActivity().runOnUiThread(() -> - showImportSnackbar(fragment.getString(R.string.install_warn_manifest_missing))); - } - // Transparency: an app-made (device) backup carries no integrity checksum. - if (okNoChecksum && fragment.getActivity() != null) { - fragment.getActivity().runOnUiThread(() -> - showImportSnackbar(fragment.getString(R.string.install_warn_no_checksum))); - } - if (fragment.getActivity() != null) { fragment.getActivity().runOnUiThread(() -> { host.setImporting(false); @@ -647,7 +649,12 @@ private void importBackupSafely(Uri sourceUri) { btnImportBackup.setText(fragment.getString(R.string.install_btn_import_backup)); selectedBackupFile = fileName; host.updateDynamicButtons(); - showImportSnackbar(fragment.getString(R.string.install_msg_import_success)); + // One snackbar only (Snackbar replaces, never queues): fold the + // no-checksum / no-manifest transparency into the final message. + showImportSnackbar(fragment.getString( + okNoChecksum ? R.string.install_warn_no_checksum + : okNoManifest ? R.string.install_warn_manifest_missing + : R.string.install_msg_import_success)); }); } } catch (Exception e) {