Skip to content

Commit d52ce68

Browse files
committed
fix: Fix for downloading update when sha verification failes
1 parent ea29675 commit d52ce68

5 files changed

Lines changed: 80 additions & 24 deletions

File tree

‎app/src/main/java/com/drivehub/kamera/OtaController.java‎

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import androidx.appcompat.app.AppCompatActivity;
1919
import androidx.core.content.ContextCompat;
20+
import androidx.core.content.FileProvider;
2021
import java.util.Locale;
2122

2223
final class OtaController {
@@ -147,7 +148,7 @@ private void showProgressDialog(OtaUpdateManager.UpdateInfo info, long downloadI
147148
OtaDialogs.ProgressDialogHandle handle = OtaDialogs.showProgressDialog(
148149
activity,
149150
activity.getString(R.string.ota_dialog_download_started_message, info.latestVersion),
150-
this::openDownloads,
151+
null,
151152
() -> retryDownload(downloadId),
152153
() -> installUpdate(downloadId)
153154
);
@@ -298,10 +299,15 @@ private void startVerification(long downloadId, TextView statusView, View instal
298299

299300
private void installUpdate(long downloadId) {
300301
try {
301-
Uri apkUri = resolveDownloadedApkUri(downloadId);
302-
if (apkUri == null) {
302+
java.io.File apkFile = resolveDownloadedApkFile(downloadId);
303+
if (apkFile == null || !apkFile.exists()) {
303304
throw new IllegalStateException("Downloaded APK not found");
304305
}
306+
Uri apkUri = FileProvider.getUriForFile(
307+
activity,
308+
BuildConfig.APPLICATION_ID + ".fileprovider",
309+
apkFile
310+
);
305311
Intent installIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
306312
installIntent.setData(apkUri);
307313
installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
@@ -324,6 +330,24 @@ private void installUpdate(long downloadId) {
324330
}
325331
}
326332

333+
private java.io.File resolveDownloadedApkFile(long downloadId) throws Exception {
334+
Uri apkUri = resolveDownloadedApkUri(downloadId);
335+
if (apkUri == null) return null;
336+
if ("file".equalsIgnoreCase(apkUri.getScheme())) {
337+
return new java.io.File(apkUri.getPath());
338+
}
339+
DownloadManager dm = activity.getSystemService(DownloadManager.class);
340+
if (dm == null) return null;
341+
try (Cursor cursor = dm.query(new DownloadManager.Query().setFilterById(downloadId))) {
342+
if (cursor == null || !cursor.moveToFirst()) return null;
343+
String localUri = cursor.getString(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_LOCAL_URI));
344+
if (localUri == null || localUri.isEmpty()) return null;
345+
Uri local = Uri.parse(localUri);
346+
if (!"file".equalsIgnoreCase(local.getScheme())) return null;
347+
return new java.io.File(local.getPath());
348+
}
349+
}
350+
327351
private Uri resolveDownloadedApkUri(long downloadId) throws Exception {
328352
DownloadManager dm = activity.getSystemService(DownloadManager.class);
329353
if (dm == null) return null;
@@ -517,16 +541,6 @@ private void renderSourceStatus(TextView view, OtaUpdateManager.SourceStatus sta
517541
// Helpers
518542
// -------------------------------------------------------------------------
519543

520-
private void openDownloads() {
521-
Intent intent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
522-
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
523-
try {
524-
activity.startActivity(intent);
525-
} catch (Throwable t) {
526-
Toast.makeText(activity, R.string.ota_toast_open_downloads_failed, Toast.LENGTH_SHORT).show();
527-
}
528-
}
529-
530544
private CharSequence progressStatusText(int status, int pct, long downloaded, long total, int reason) {
531545
if (status == DownloadManager.STATUS_SUCCESSFUL) {
532546
return activity.getString(R.string.ota_progress_complete);

‎app/src/main/java/com/drivehub/kamera/OtaDialogs.java‎

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.app.Dialog;
44
import android.content.Context;
5+
import android.content.res.ColorStateList;
56
import android.graphics.Color;
67
import android.graphics.drawable.ColorDrawable;
78
import android.graphics.drawable.GradientDrawable;
@@ -95,11 +96,20 @@ static ProgressDialogHandle showProgressDialog(
9596
if (title != null) {
9697
title.setText(titleText);
9798
}
99+
if (progress != null) {
100+
int accentColor = UiPrefs.getAccentColorInt(UiPrefs.getPrefs(context));
101+
progress.setProgressTintList(ColorStateList.valueOf(accentColor));
102+
progress.setIndeterminateTintList(ColorStateList.valueOf(accentColor));
103+
}
98104
if (openDownloadsButton != null) {
99-
stylePrimaryButton(context, openDownloadsButton);
100-
openDownloadsButton.setOnClickListener(v -> {
101-
if (onOpenDownloads != null) onOpenDownloads.run();
102-
});
105+
if (onOpenDownloads != null) {
106+
stylePrimaryButton(context, openDownloadsButton);
107+
openDownloadsButton.setOnClickListener(v -> {
108+
if (onOpenDownloads != null) onOpenDownloads.run();
109+
});
110+
} else {
111+
openDownloadsButton.setVisibility(View.GONE);
112+
}
103113
}
104114
if (retryDownloadButton != null) {
105115
stylePrimaryButton(context, retryDownloadButton);

‎app/src/main/java/com/drivehub/kamera/OtaUpdateManager.java‎

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
final class OtaUpdateManager {
1616

17+
private static final String OTA_STAGING_DIR = "ota_updates";
1718
private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();
1819
private static final Handler MAIN_HANDLER = new Handler(Looper.getMainLooper());
1920

@@ -136,12 +137,13 @@ static long enqueueDownload(Context context, UpdateInfo info) {
136137
? String.format(Locale.US, "mg4-360-cam-%s.apk", info.latestVersion)
137138
: info.assetFileName
138139
);
140+
File targetFile = prepareStagingFile(context, fileName);
139141

140142
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(info.downloadUrl))
141143
.setTitle("360 Cam Update")
142144
.setDescription("Downloading version " + info.latestVersion)
143145
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
144-
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
146+
.setDestinationUri(Uri.fromFile(targetFile))
145147
.setAllowedOverMetered(true)
146148
.setAllowedOverRoaming(true);
147149

@@ -160,4 +162,34 @@ static void verifyDownloadedApk(Context context, long downloadId, Uri apkUri, Up
160162
private static String sanitizeFileName(String fileName) {
161163
return fileName.replaceAll("[^A-Za-z0-9._-]", "_");
162164
}
165+
166+
private static File prepareStagingFile(Context context, String fileName) {
167+
File baseDir = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
168+
if (baseDir == null) {
169+
throw new IllegalStateException("App staging directory unavailable");
170+
}
171+
File stagingDir = new File(baseDir, OTA_STAGING_DIR);
172+
if (!stagingDir.exists() && !stagingDir.mkdirs()) {
173+
throw new IllegalStateException("Could not create OTA staging directory");
174+
}
175+
176+
cleanupOldStagedFiles(stagingDir, fileName);
177+
File targetFile = new File(stagingDir, fileName);
178+
if (targetFile.exists() && !targetFile.delete()) {
179+
throw new IllegalStateException("Could not replace existing OTA package");
180+
}
181+
return targetFile;
182+
}
183+
184+
private static void cleanupOldStagedFiles(File stagingDir, String keepFileName) {
185+
File[] files = stagingDir.listFiles();
186+
if (files == null) return;
187+
for (File file : files) {
188+
if (file == null || !file.isFile()) continue;
189+
if (keepFileName != null && keepFileName.equals(file.getName())) continue;
190+
// Only clean the app's private OTA staging area, never the public Downloads folder.
191+
// Old manually downloaded APKs remain untouched outside this directory.
192+
file.delete();
193+
}
194+
}
163195
}

‎app/src/main/res/values-de/strings.xml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@
6060
<string name="ota_status_check_failed">Tippen zum erneuten Prüfen</string>
6161
<string name="ota_dialog_title">OTA-Update</string>
6262
<string name="ota_dialog_up_to_date_message">Es wurde keine neuere Version gefunden. Du kannst die Suche manuell aktualisieren.</string>
63-
<string name="ota_dialog_update_available_message">Eine neuere Version %1$s ist verfügbar. Tippe den Update-Tag erneut an, um sie in Downloads herunterzuladen.</string>
63+
<string name="ota_dialog_update_available_message">Eine neuere Version %1$s ist verfügbar. Tippe den Update-Tag erneut an, um sie herunterzuladen und zu verifizieren.</string>
6464
<string name="ota_dialog_check_failed_message">Die Update-Prüfung ist fehlgeschlagen. Tippe auf Aktualisieren, um es erneut zu versuchen.</string>
6565
<string name="ota_dialog_mobile_warning_message">Du bist aktuell über Mobilfunk verbunden. Der Download von Version %1$s verbraucht das Datenvolumen der internen SIM im Auto. Möchtest du wirklich fortfahren?</string>
66-
<string name="ota_dialog_download_started_message">Das Update für Version %1$s wird jetzt in Downloads heruntergeladen.</string>
66+
<string name="ota_dialog_download_started_message">Das Update für Version %1$s wird jetzt geschützt heruntergeladen.</string>
6767
<string name="ota_dialog_download_failed_message">Der Update-Download konnte nicht gestartet werden (%1$s).</string>
6868
<string name="ota_dialog_install_failed_message">Der Installer konnte nicht geöffnet werden (%1$s).</string>
6969
<string name="ota_error_no_hash">Im neuesten Release fehlt ein SHA-256-Asset für die APK</string>
@@ -75,7 +75,7 @@
7575
<string name="ota_progress_running_unknown">Lädt herunter… %1$s empfangen</string>
7676
<string name="ota_progress_paused">Download pausiert bei %1$d%%. Warte auf Fortsetzung…</string>
7777
<string name="ota_progress_paused_reason">Download pausiert bei %1$d%% (%2$s)</string>
78-
<string name="ota_progress_complete">Download abgeschlossen. Die APK liegt jetzt in Downloads.</string>
78+
<string name="ota_progress_complete">Download abgeschlossen. Paketintegrität wird geprüft…</string>
7979
<string name="ota_progress_verifying">Prüfe Download-Integrität…</string>
8080
<string name="ota_progress_verified">Integritätsprüfung bestanden. Bereit zur Installation.</string>
8181
<string name="ota_progress_integrity_failed">Integritätsprüfung fehlgeschlagen (%1$s).</string>

‎app/src/main/res/values/strings.xml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@
6060
<string name="ota_status_check_failed">Tap to retry update check</string>
6161
<string name="ota_dialog_title">OTA Update</string>
6262
<string name="ota_dialog_up_to_date_message">No newer version was found. You can refresh the release check manually.</string>
63-
<string name="ota_dialog_update_available_message">A newer version %1$s is available. Tap the update tag again to download it to Downloads.</string>
63+
<string name="ota_dialog_update_available_message">A newer version %1$s is available. Tap the update tag again to download and verify it.</string>
6464
<string name="ota_dialog_check_failed_message">The update check failed. Tap refresh to try again.</string>
6565
<string name="ota_dialog_mobile_warning_message">You are currently connected via mobile data. Downloading version %1$s will use the car\'s internal SIM data volume. Are you sure you want to continue?</string>
66-
<string name="ota_dialog_download_started_message">The update for version %1$s is now being downloaded to Downloads.</string>
66+
<string name="ota_dialog_download_started_message">The update for version %1$s is now being downloaded securely.</string>
6767
<string name="ota_dialog_download_failed_message">The update download could not be started (%1$s).</string>
6868
<string name="ota_dialog_install_failed_message">The installer could not be opened (%1$s).</string>
6969
<string name="ota_error_no_hash">Latest release has no SHA-256 asset for the APK</string>
@@ -75,7 +75,7 @@
7575
<string name="ota_progress_running_unknown">Downloading… %1$s received</string>
7676
<string name="ota_progress_paused">Download paused at %1$d%%. Waiting to continue…</string>
7777
<string name="ota_progress_paused_reason">Download paused at %1$d%% (%2$s)</string>
78-
<string name="ota_progress_complete">Download complete. The APK is now in Downloads.</string>
78+
<string name="ota_progress_complete">Download complete. Verifying package integrity…</string>
7979
<string name="ota_progress_verifying">Verifying download integrity…</string>
8080
<string name="ota_progress_verified">Integrity check passed. Ready to install.</string>
8181
<string name="ota_progress_integrity_failed">Integrity check failed (%1$s).</string>

0 commit comments

Comments
 (0)