Skip to content

Commit fc829b1

Browse files
committed
refactor(i18n): remove French content
Make English the default resource language and remove the French locale, documentation, and historical analysis copies. Existing saved French preferences fall back to English.\n\nAdd a regression test that keeps changelog and locale content English-only.
1 parent e1738f7 commit fc829b1

88 files changed

Lines changed: 1561 additions & 8318 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitattributes‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# ── Normalisation des fins de ligne ─────────────────────────────────────────
2-
# Tous les fichiers texte sont normalisés en LF dans le dépôt
1+
# ── Line-ending normalization ────────────────────────────────────────────────
2+
# All text files are normalized to LF in the repository
33
* text=auto eol=lf
44

55
# Fichiers texte explicites
@@ -17,7 +17,7 @@
1717
*.properties text eol=lf
1818
*.html text eol=lf
1919

20-
# ── Fichiers binaires (pas de conversion, pas de diff texte) ─────────────────
20+
# ── Binary files (no conversion, no text diff) ─────────────────
2121
*.png binary
2222
*.jpg binary
2323
*.jpeg binary
@@ -33,6 +33,6 @@
3333
*.so binary
3434
*.zip binary
3535

36-
# ── Scripts Gradle Wrapper — exécutables sur Unix ────────────────────────────
36+
# ── Gradle Wrapper Scripts — executable on Unix ────────────────────────────
3737
gradlew text eol=lf
3838
gradlew.bat text eol=crlf

‎.github/security/permission-allowlist.txt‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
android.permission.SYSTEM_ALERT_WINDOW
88
android.permission.FOREGROUND_SERVICE
9-
# Exigée par foregroundServiceType="connectedDevice" à partir d'API 34 (T-910).
10-
# N'accorde aucun accès supplémentaire : elle qualifie le service de premier plan.
9+
# Required by foregroundServiceType="connectedDevice" from API 34 onward (T-910).
10+
# Grants no additional access; it classifies the foreground service.
1111
android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE
1212
android.permission.WAKE_LOCK
1313
# Posts the foreground-service notification, the only visible sign EVProfile is running.
@@ -20,14 +20,14 @@ android.car.permission.CAR_ENERGY
2020
android.car.permission.CAR_POWERTRAIN
2121
android.car.permission.CAR_VENDOR_EXTENSION
2222
android.car.permission.CONTROL_CAR_CLIMATE
23-
# --- permission DÉCLARÉE par l'app (pas demandée) ---
24-
# Exigée de l'émetteur du broadcast hardkey, en protectionLevel="signature" (T-902) :
25-
# seule une app signée avec la clé plateforme peut l'obtenir. Elle restreint un accès,
26-
# elle n'en accorde pas.
23+
# --- permission DECLARED by the app (not requested) ---
24+
# Required from the hard-key broadcast sender with protectionLevel="signature" (T-902):
25+
# only an app signed with the platform key can obtain it. It restricts access and does
26+
# not grant any.
2727
com.evsuite.profile.permission.RECEIVE_HARDKEY
2828
# External control API: signature-level permission protecting ProfileControlService.
29-
# protectionLevel="signature" → réservée aux apps signées avec la clé plateforme.
30-
# Déclarée ET demandée par EVProfile : demandée pour pouvoir émettre le broadcast.
29+
# protectionLevel="signature": reserved for apps signed with the platform key.
30+
# Declared and requested by EVProfile so it can send the broadcast.
3131
com.evsuite.profile.permission.CONTROL_PROFILES
3232
# --- network / OTA (unstable channel only; the merged-manifest gate proves stable lacks it) ---
3333
android.permission.INTERNET

‎.gitignore‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
build/
44
**/build/
55

6-
# Local config (ne jamais committer — contient les chemins locaux SDK)
6+
# Local config (never commit — contains local SDK paths)
77
local.properties
88

99
# mokup
1010
mockup/
1111

12-
# Analyse interne (non commitée) — docs de travail générés
12+
# Internal analysis (uncommitted) — generated working docs
1313
analysis/DIFF_2.7.0.md
1414
analysis/DIFF_2.7.0.full.diff
1515
analysis/SOH_feasibility.md
@@ -28,7 +28,7 @@ analysis/FEATURE_BACKLOG.md
2828
*.ipr
2929
.DS_Store
3030

31-
# Keystore & secrets de signature (ne jamais committer)
31+
# Keystore & signing secrets (never commit)
3232
*.jks
3333
*.keystore
3434
keystore.properties
@@ -39,7 +39,7 @@ signing.properties
3939
*.log
4040

4141

42-
# mise : mise.toml est COMMITÉ (il décrit le build). Seules les surcharges
43-
# locales, machine-spécifiques, sont ignorées.
42+
# mise: mise.toml is COMMITTED (it describes the build). Only overloads
43+
# local, machine-specific, are ignored.
4444
mise.local.toml
4545
.mise.local.toml

‎AGENTS.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ It is the reference for interactive write sequencing and user-visible refusal ha
1818
EVHardware remains authoritative for shared primitives, firmware routing and low-level
1919
safety gates.
2020

21+
## Language
22+
23+
EVProfile is maintained in English only. Changelog entries, documentation, source comments,
24+
developer tooling output and the default Android resources must be English. Do not add a
25+
French documentation variant or French locale option. Other supported UI translations stay
26+
in their qualified `values-<locale>` directories; English stays in unqualified `values`.
27+
2128
## The one rule that shapes everything
2229

2330
**A write is a physical act.** Every code path that reaches the vehicle is gated on

‎CHANGELOG.md‎

Lines changed: 43 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,26 @@ All notable changes to this project are documented here. Format follows
88

99
### Fixed
1010

11-
- **`applyProfile` ne rapporte plus une réussite quand le portail l'a refusée.** Le service
12-
renvoyait `ok = true` avec le verdict `REFUSED_MOVING` ou `REFUSED_UNKNOWN_SPEED` : dans
13-
l'historique d'EVTasker, la même ligne disait « appliqué » et « refusé ». Les réglages
14-
soumis au portail ne partaient pas, et un appelant qui ne lisait que l'indicateur n'avait
15-
aucun moyen de le savoir. `ok` suit désormais le verdict.
11+
- **`applyProfile` no longer reports success when the gateway refused the request.** The
12+
service returned `ok = true` with a `REFUSED_MOVING` or `REFUSED_UNKNOWN_SPEED` verdict,
13+
so the same EVTasker history entry said both "applied" and "refused." The settings sent
14+
through the gateway were not written, and callers that only read the success flag could
15+
not detect the refusal. `ok` now follows the verdict.
1616

1717
## [3.0.1] - 2026-08-25
1818

1919
### Fixed
2020

21-
- **Le service survit sur une voiture qui n'a pas accordé le Bluetooth.** Le service déclare
22-
le type de premier plan `connectedDevice`, et depuis Android 14 ce type exige
23-
BLUETOOTH_CONNECT au moment précis où le service passe en premier plan — une permission
24-
déclarée par l'application mais jamais demandée. Le type n'est désormais revendiqué que
25-
tant que la permission qui le porte est détenue, et il est repris dès qu'elle est accordée,
26-
sans attendre le prochain démarrage.
27-
- **La liste des appareils appairés n'est plus vide sans raison.** BLUETOOTH_CONNECT est
28-
maintenant demandée à l'ouverture de l'application ; un refus ne coûte que la détection du
29-
téléphone, comme avant.
30-
- **La notification du service est visible.** POST_NOTIFICATIONS n'était pas déclarée : depuis
31-
Android 13, le seul signe visible que EVProfile tourne était supprimé en silence.
21+
- **The service remains running when the vehicle has not granted Bluetooth access.** The
22+
service declares the `connectedDevice` foreground-service type, which requires
23+
`BLUETOOTH_CONNECT` at the exact moment the service enters the foreground on Android 14
24+
and later. The app declared that permission but never requested it. The service now claims
25+
the type only while the supporting permission is held and reasserts it as soon as the
26+
permission is granted, without waiting for the next startup.
27+
- **The paired-device list is no longer empty without explanation.** `BLUETOOTH_CONNECT` is
28+
now requested when the app opens; denying it only disables phone detection, as before.
29+
- **The service notification is visible.** `POST_NOTIFICATIONS` was missing, so Android 13
30+
and later silently removed the only visible indication that EVProfile was running.
3231

3332
## [3.0.0] - 2026-08-15
3433

@@ -54,39 +53,37 @@ All notable changes to this project are documented here. Format follows
5453

5554
### Added
5655

57-
- **Un bouton Automatisation dans la barre du haut, quand EVTasker est installé.** EVProfile
58-
règle la voiture à la main, EVTasker automatise ce réglage : les deux se cherchaient par le
59-
lanceur. Le bouton n'apparaît que si l'app est là — un bouton qui n'ouvre rien vaut moins
60-
que pas de bouton — et la visibilité est réévaluée à chaque reprise, pour qu'une
61-
installation faite pendant que EVProfile tourne n'exige pas un redémarrage. Le clic
62-
revérifie l'intent : entre l'affichage et le doigt, l'app peut avoir été désinstallée.
63-
- **Le sélecteur de profils est exposé aux autres apps de la suite** (`showProfilePicker()`
64-
sur `IProfileControl`, toujours fermé par la permission signature). EVTasker peut
65-
demander à EVProfile de poser sa liste de profils devant le conducteur au lieu de choisir
66-
à sa place. Refusé en roulant, comme l'application d'un profil, et signalé comme tel au
67-
lieu d'un overlay qui n'apparaît simplement pas : une app qui n'apprend que « rien ne
68-
s'est passé » ne peut pas distinguer une voiture en mouvement d'une liste de profils vide.
69-
- **Partager un diagnostic.** Le dialog Diagnostic peut envoyer le rapport complet vers une
70-
instance PrivateBin (paste.chapril.org) : chiffré, protégé par mot de passe, expirant au
71-
bout d'une heure, et le serveur ne détient jamais la clé. L'envoi est confirmé à chaque
72-
fois — le rapport quitte la voiture, ce n'est pas une décision à prendre à la place de
73-
l'utilisateur. Le lien et le mot de passe sont écrits dans le journal, seul endroit où on
74-
peut les relire une fois le toast disparu ; les lignes de partage sont retirées des
75-
rapports envoyés ensuite, pour qu'un second envoi ne livre pas le premier. Absent du build
76-
stable, qui ne déclare pas la permission INTERNET.
77-
- **Trois appuis sur la version, dans la fenêtre À propos, ouvrent le Diagnostic.** Geste
78-
caché : le rapport contient le firmware et les journaux, il n'a rien à faire sous le doigt
79-
d'un passager qui explore l'écran.
56+
- **An Automation button appears in the top bar when EVTasker is installed.** EVProfile
57+
configures the vehicle manually while EVTasker automates those settings; previously the
58+
launcher was the only way to move between them. The button appears only when the app is
59+
present, and its visibility is reevaluated on every resume so installing EVTasker while
60+
EVProfile is running does not require a restart. The click validates the intent again in
61+
case the app was removed after the button appeared.
62+
- **The profile picker is exposed to other EVSuite apps** through `showProfilePicker()` on
63+
`IProfileControl`, still protected by the signature permission. EVTasker can ask EVProfile
64+
to show the driver the profile list instead of choosing on their behalf. Like applying a
65+
profile, this is refused while moving and the refusal is reported explicitly; callers can
66+
distinguish a moving vehicle from an empty profile list.
67+
- **Diagnostic sharing.** The Diagnostic dialog can send the complete report to a PrivateBin
68+
instance (paste.chapril.org). It is encrypted, password-protected, expires after one hour,
69+
and the server never receives the key. Every upload requires confirmation because the
70+
report leaves the vehicle. The link and password are written to the log so they remain
71+
available after the toast disappears. Sharing entries are removed from later reports so a
72+
second upload does not disclose the first. This capability is absent from stable builds,
73+
which do not declare the `INTERNET` permission.
74+
- **Three taps on the version in About open Diagnostics.** This is intentionally hidden: the
75+
report contains firmware information and logs and should not be exposed as a normal action
76+
to passengers exploring the screen.
8077

8178
### Changed
8279

83-
- **La lecture des touches ★ du volant vient de EVHardware** (`PhysicalButtonEventDecoder`),
84-
qui connaît les alias de keycode par firmware. Deux conséquences visibles : un appui long
85-
maintenu ne déclenche plus l'action en boucle mais une seule fois, et un relâchement sans
86-
appui préalable ne déclenche plus rien.
87-
- **La version firmware affichée dans À propos est lue par la librairie.** `FirmwareHelper`
88-
lisait une seconde fois les mêmes propriétés système que la détection de génération ; il
89-
est supprimé.
80+
- **Steering-wheel ★ button events now come from EVHardware** through
81+
`PhysicalButtonEventDecoder`, which knows each firmware generation's key-code aliases. A
82+
held long press now triggers the action once instead of repeatedly, and a release without
83+
a preceding press no longer triggers anything.
84+
- **The firmware version shown in About is read by the library.** `FirmwareHelper`
85+
duplicated the system-property reads already used for generation detection and has been
86+
removed.
9087
- **Crash reporting now comes from EVHardware** (`com.evsuite.hardware.diag.CrashLogger`)
9188
instead of being carried here. The report gains the full stack trace as the platform
9289
prints it, an atomic write so a second failure mid-write cannot destroy the previous

0 commit comments

Comments
 (0)