App 2.3.0: Server tab, live telemetry to the car server

- New Server tab: server URL, ingest token and installation id, with
  Save, Test connection (health, then a read-only token check) and the
  config-file import that upstream removed (app folder / USB stick first,
  document picker as fallback). Settings are kept encrypted and read on
  every use, so the service picks up a change without a restart. Each
  installation generates its own id; the inherited upstream UUID and
  the baked-in CONSUMPTION_API_* build fields are gone.
- Live telemetry restored from before ea8032a (TelemetryPayload,
  UploadCadence, UploadSettings, GPS) and sent in batches to
  POST /v1/telemetry instead of ABRP; the server forwards to ABRP. Adds
  ext_temp, voltage and current. Unsent samples queue in memory (about
  8 h) while offline.
- Upload tab: the live-telemetry switch and cadence controls work again;
  the dead service and autostart switches are removed.
- Manifest: location permissions and foreground service types.
- Unit tests compile again: 114 (stable) / 136 (unstable) pass. Tests
  for the deleted AbrpApi and HeadUnitWeather removed; new tests for
  ServerConfig and TelemetryQueue. Lint passes.

Not yet tried on the car.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-17 14:23:04 +02:00
co-authored by Claude Opus 5.5
parent c253876ed2
commit 6145736c97
27 changed files with 1590 additions and 287 deletions
@@ -1,50 +0,0 @@
package com.evsuite.abrp;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
/**
* [T-912] Credentials must reach ABRP in the request body. A URL is logged by
* proxies, CDNs and crash reporters; a body is not.
*/
public class AbrpApiTest {
@Test
public void endpointUrlCarriesNoCredentials() {
assertFalse(AbrpApi.API_URL.contains("?"));
assertFalse(AbrpApi.API_URL.contains("api_key"));
assertFalse(AbrpApi.API_URL.contains("token"));
}
@Test
public void endpointIsHttps() {
assertTrue(AbrpApi.API_URL.startsWith("https://"));
assertTrue(AbrpApi.VERIFY_URL.startsWith("https://"));
}
/** [T-913] The Test button must not be able to write telemetry. */
@Test
public void credentialCheckDoesNotTargetTheTelemetryWriteEndpoint() {
assertFalse("le test de connexion ne doit jamais viser /tlm/send",
AbrpApi.VERIFY_URL.contains("/tlm/send"));
assertTrue(AbrpApi.VERIFY_URL.contains("get_next_charge"));
}
@Test
public void bodyCarriesAllThreeParameters() throws Exception {
String body = AbrpApi.formBody("KEY", "TOK", "{\"utc\":1}");
assertTrue(body.contains("api_key=KEY"));
assertTrue(body.contains("token=TOK"));
assertTrue(body.contains("tlm="));
}
@Test
public void bodyIsFormEncoded() throws Exception {
// A token with URL-significant characters must not break the body layout.
String body = AbrpApi.formBody("a+b/c", "d&e=f", "{\"utc\":1}");
assertEquals("api_key=a%2Bb%2Fc&token=d%26e%3Df&tlm=%7B%22utc%22%3A1%7D", body);
}
}