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:
@@ -85,6 +85,12 @@ final class LogOutbox {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Removes what waits under names starting with [prefix]. */
|
||||
static synchronized void dropWaiting(Context context, String prefix) {
|
||||
File dir = new File(context.getFilesDir(), DIR);
|
||||
for (String name : waiting(dir)) if (name.startsWith(prefix)) new File(dir, name).delete();
|
||||
}
|
||||
|
||||
/** Sends what waits, unless the last attempt failed less than {@link #RETRY_MS} ago. Blocking:
|
||||
* call it off the main thread. */
|
||||
static void sendIfDue(Context context) {
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.evsuite.abrp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.NoRouteToHostException;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
/**
|
||||
* Why an update check failed, in words for the update log, and what the car's networks look
|
||||
* like. Built from an error's type and an HTTP status only, because an error's own text can carry
|
||||
* the server's address: nothing here holds a URL or a credential. Android-free and unit-tested.
|
||||
*/
|
||||
final class UpdateDiagnosis {
|
||||
|
||||
private static final Pattern STATUS = Pattern.compile("^Release API returned (\\d{3})$");
|
||||
|
||||
private UpdateDiagnosis() {}
|
||||
|
||||
/** One line about a failed step. */
|
||||
static String failure(Throwable t) {
|
||||
if (t == null) return "unknown failure";
|
||||
String type = " (" + t.getClass().getSimpleName() + ")";
|
||||
if (t instanceof UnknownHostException) return "the name could not be looked up: no data connection, or no name service" + type;
|
||||
if (t instanceof SocketTimeoutException) return "no answer in time: a very slow or blocked connection" + type;
|
||||
if (t instanceof ConnectException || t instanceof NoRouteToHostException) return "no connection could be made" + type;
|
||||
if (t instanceof SSLException) return "the secure connection failed: something in between may have answered, or the head unit's clock is wrong" + type;
|
||||
if (t instanceof SocketException) return "the connection broke off" + type;
|
||||
if (t instanceof IOException && t.getMessage() != null) {
|
||||
Matcher status = STATUS.matcher(t.getMessage());
|
||||
if (status.matches()) return status(Integer.parseInt(status.group(1)));
|
||||
if (t.getMessage().equals("Invalid release response")) return "the answer was not a list of releases";
|
||||
}
|
||||
return "failed" + type;
|
||||
}
|
||||
|
||||
/** What a status from the car server means here. */
|
||||
static String status(int code) {
|
||||
String what;
|
||||
if (code >= 300 && code < 400) what = "something in between redirected it, as a SIM without data may";
|
||||
else if (code == 401 || code == 403) what = "the server refuses the car's token";
|
||||
else if (code == 404) what = "the server does not know this address";
|
||||
else if (code >= 500) what = "the server or the forge behind it has a problem";
|
||||
else what = "not what was expected";
|
||||
return "the server answered HTTP " + code + ": " + what;
|
||||
}
|
||||
|
||||
/** The outside-world test: a 204 is the internet working; anything else stands in between. */
|
||||
static String internet(int code) {
|
||||
if (code == 204) return "the internet works (HTTP 204)";
|
||||
return "something in between answered HTTP " + code + " instead, as a SIM without data may";
|
||||
}
|
||||
|
||||
/** One network as Android sees it. */
|
||||
static String network(List<String> transports, boolean internet, boolean validated,
|
||||
boolean active, boolean roaming) {
|
||||
return (transports.isEmpty() ? "unknown type" : String.join("+", transports))
|
||||
+ (active ? ", in use" : "")
|
||||
+ (internet ? ", offers internet" : ", no internet")
|
||||
+ (validated ? ", confirmed by Android" : ", not confirmed by Android")
|
||||
+ (roaming ? ", roaming" : "");
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ import java.util.Locale;
|
||||
*/
|
||||
final class UpdateLog {
|
||||
|
||||
static final int MAX_LINES = 10;
|
||||
static final int MAX_LINES = 40;
|
||||
private static final String PREFS = "update_log";
|
||||
private static final String KEY = "lines";
|
||||
private static final String KEY_VERSION = "version";
|
||||
|
||||
Reference in New Issue
Block a user