App 2.43.5: update checks log what happens

Each check writes down the networks Android sees, the server's name lookup,
how a failure happened and how many reports wait, and on a failure whether
the internet answers at all, to tell a SIM without data from a server that is
down. The report goes to a USB stick and, once online, the server. No address
or token is written. Tried on the emulator. Not tried on the car.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
This commit is contained in:
2026-11-01 10:21:15 +01:00
co-authored by Claude Opus 5.5
parent 6b55bec419
commit e52d7f01fc
14 changed files with 301 additions and 15 deletions
@@ -5,6 +5,11 @@ import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -58,7 +63,8 @@ final class UpdateHook {
"Update available: " + update.versionName,
android.widget.Toast.LENGTH_LONG).show());
} catch (Throwable t) {
Log.w(TAG, "Startup update check failed", t);
Log.w(TAG, "Startup update check failed: " + t.getClass().getSimpleName());
UpdateLog.record(app, "Check at start: " + UpdateDiagnosis.failure(t));
}
}, "ota-startup-check").start();
}
@@ -78,24 +84,46 @@ final class UpdateHook {
return;
}
new Thread(() -> {
long startedMs = System.currentTimeMillis();
List<String> steps = new ArrayList<>();
step(app, steps, "Check started, app " + BuildConfig.VERSION_NAME);
String message;
try {
for (String network : UpdateNetworkCheck.networks(app)) step(app, steps, network);
ServerConfig config = ServerConfig.get(app);
String host = config.isConfigured() ? OtaUpdater.allowedHost(config) : null;
if (host != null) step(app, steps, UpdateNetworkCheck.lookup(host));
message = runCheck(app, listener, main);
} catch (Throwable t) {
Log.w(TAG, "Update check threw", t);
// The class only: a network error's text can carry the server's address.
message = "Update check failed (" + t.getClass().getSimpleName() + ")";
Log.w(TAG, "Update check threw: " + t.getClass().getSimpleName());
message = "Update check failed: " + UpdateDiagnosis.failure(t);
// Is it the server or the connection? The answer to "is my SIM out of data".
step(app, steps, UpdateNetworkCheck.internet());
} finally {
checking.set(false);
}
UpdateLog.record(app, "Check: " + message);
step(app, steps, "Check: " + message);
String waiting = LogOutbox.status(app);
if (waiting != null) step(app, steps, "Reports: " + waiting);
if (listener != null) {
final String result = message;
main.post(() -> listener.onResult(result));
}
// After the answer: without a connection this waits for the send to fail.
String name = "update-check-" + new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.US)
.format(new Date(startedMs)) + ".txt";
// Only the newest waits: repeated checks offline must not push out a recording.
LogOutbox.dropWaiting(app, "update-check-");
SignalRecorder.saveCopies(app, "update_check.txt", name, steps);
}, "ota-check").start();
}
/** One step of a check: on the Logs tab now, and in the report saved when it ends. */
private static void step(Context app, List<String> steps, String what) {
UpdateLog.record(app, what);
steps.add(what);
}
/**
* Installs the newest car build from the top folder of a USB stick (UsbUpdate), with the
* same checks as the over-the-air update except the server. Background thread; [listener]
@@ -195,14 +223,14 @@ final class UpdateHook {
try {
expectedHash = OtaUpdater.fetchExpectedSha256(update, config);
} catch (IOException e) {
Log.w(TAG, "OTA hash unavailable: " + e.getMessage());
return "Update refused: no SHA-256 verification";
Log.w(TAG, "OTA hash unavailable: " + e.getClass().getSimpleName());
return "Update refused, no SHA-256 verification: " + UpdateDiagnosis.failure(e);
}
File apk = OtaUpdater.download(update, expectedHash, config, percent -> {
if (listener != null) main.post(() -> listener.onProgress(percent));
});
if (apk == null) return "Download or SHA-256 verification failed ("
+ update.versionName + ")";
+ update.versionName + "): " + OtaUpdater.downloadProblem;
switch (OtaUpdater.install(app, apk)) {
case SESSION_STARTED: