Everything posted by Vitaly
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.80-beta🎤 Wake-word diag : voir si "Hey Jarvis" réagit Problème terrain Tu cries "Hey Jarvis" → rien ne bouge → tu penses que c'est cassé. En réalité le modèle scorait probablement entre 0.01 et 0.10, soit 1% à 10% de la barre — invisible à l'œil. Le seuil de détection était à 0.5, donc inatteignable dans un habitacle. Changements Seuil 0.5 → 0.3 : la barre se déclenchera désormais à partir de 30% (encore au-dessus du bruit ambiant HVAC/moteur d'après les ROC openWakeWord). Score live affiché en clair sous la barre : score=0.034 · peak30s=0.087 (il y a 12s) · seuil=0.30 → tu vois immédiatement si le modèle réagit, même sans franchir le seuil. Log auto toutes les 5s dans l'onglet Logs : WakeWordEngine: diag: score=0.087 max5s=0.142 peak30s=0.213 thr=0.30 → diagnosable a posteriori sans regarder Diag en direct. Comment tester Diag → onglet Voice → activer "Mot d'éveil" (auto-démarre l'écoute) Crier "HEY JARVIS" en prononciation anglaise (« hey djahr-viss ») Regarder le triple score=... · peak30s=... · seuil=0.30 Si peak30s monte à 0.20+ → le modèle te perçoit, prononciation à peaufiner Si peak30s reste à 0.0X → micro OK mais modèle insensible à ta voix Si peak30s atteint 0.30 → BIP, détection validée Onglet Logs → filtrer "WakeWordEngine" pour voir l'historique 5s Note Le modèle hey_jarvis_v0.1 est entraîné sur des voix anglophones US/UK uniquement. Une prononciation française « hé jar-vis » score 3-10× moins. C'est le placeholder en attendant l'entraînement custom du wake-word "Ok DashCast" (Phase 3 Voice, à venir). LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.79-beta🚀 Phase C — Basculement par défaut DEFAULT_USE_PROXY_DAEMON : false → true Pourquoi maintenant Phase A (couches 1→4) a verrouillé la disponibilité 24/7 du daemon : Couche 1 (v1.2.75) — triggers BOOT_COMPLETED + MY_PACKAGE_REPLACED Couche 2 (v1.2.73) — ProxyKeeperService foreground 24/7 Couche 3 (v1.2.70) — daemon hardening (oom_score -900, PID lock, self-heal) Couche 4 (v1.2.78) — cooldown adaptatif + métriques persistantes Le daemon est désormais le chemin nominal pour toutes les opérations ADB. Impact utilisateur Profil Comportement Nouvel install ✅ Bascule auto sur le proxy daemon Install existant n'ayant jamais touché le toggle Beta Engine ✅ Bascule auto Install existant ayant déjà touché le toggle 🔒 Choix préservé (SharedPreferences) Filet de sécurité BetaEngineGateway conserve le fallback transparent : tout échec du chemin proxy retombe automatiquement sur AdbLocalClient legacy. Aucune régression possible côté UX — au pire, latence ADB legacy. Comment vérifier le basculement Système → "Générer le rapport" → section "9. BETA PROXY METRICS" : cold_spawns ou rebroadcasts qui montent à chaque action ADB ⇒ proxy actif Si seuls fails_* montent ⇒ fallback legacy en cours Prochaine étape Si tout reste stable une semaine en terrain → merge phase-A-proxy-recovery vers main + tag stable v1.3.0. LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.78-beta✨ Phase A close — Couche 4 : cooldown adaptatif + métriques Clôture de la défense en profondeur (4/4 couches). Cooldown adaptatif (1s → 2s → 4s → 8s → 10s) Avant : flat 10s entre chaque tentative de reconnect → KeeperService réagissait lentement quand le daemon mourait. Maintenant : premier retry en ≤1s, ramping seulement si les fails s'accumulent. Reset à 0 dès qu'un connect réussit. ERR_NO_APK fast-path Le PM a une fenêtre de race sub-seconde après une OTA pendant laquelle il n'a pas encore indexé notre APK. Quand le script bootstrap remonte ERR_NO_APK, on bypass le cooldown → retry immédiat à la prochaine attempt. Plus de "10s d'attente bête" post-update. Métriques persistantes (BetaProxyMetrics) 6 compteurs stockés en SharedPreferences (survivent aux OOM kills) : Métrique Sens cold_spawns Daemon spawné via app_process64 (chemin lourd ~2s) rebroadcasts Fast-path REBROADCAST (daemon déjà vivant, ~3ms) fails_no_apk Race PM post-OTA (récupéré au retry suivant) fails_timeout Bootstrap OK mais pas de broadcast en 6s fails_other Erreur transport ADB (ADB off, dex2oat, SELinux…) binder_zombies Binder cached mort, clear par DeathRecipient Visibles dans le rapport Système sous "9. BETA PROXY METRICS" — utile pour spotter une dérive long-terme sans scraper les logs. Récap final Phase A Couche Rôle Statut 3 — Daemon hardening OOM -900, PID lock, self-heal ✅ v1.2.70 2 — KeeperService FG 24/7 Surveillance permanente 10s ✅ v1.2.73 1 — Triggers proactifs BOOT_COMPLETED, MY_PACKAGE_REPLACED ✅ v1.2.75 4 — UX recovery Cooldown adaptatif + métriques ✅ v1.2.78 Prochaine étape v1.2.79 / Phase C : flipper DEFAULT_USE_PROXY_DAEMON=true après validation terrain de Phase A → le proxy daemon devient le chemin par défaut pour tous les nouveaux installs. LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.77-beta🐛 Fix — Notification "Cluster : arrêté" fantôme Symptôme Après avoir arrêté la projection cluster, une notification permanente DashCast — Cluster : arrêté restait collée dans le shade, impossible à effacer en swipant. Cause ClusterService.stopProjectionNoAdb() re-postait une notification setOngoing(true) via NotificationManager.notify() juste avant stopSelf(). Comme cette notif n'était plus attachée au token foreground du service (juste posée via NM), elle survivait à la destruction du service et restait non-dismissible à vie. Fix Sur stop : stopForeground(STOP_FOREGROUND_REMOVE) → retire la notif FG NotificationManager.cancel(NOTIF_ID) → cancel explicite ceinture+bretelles stopSelf() Pas de notification = rien à effacer. LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.76-beta✨ Bouton Redémarrer dans Système Plus besoin d'appuyer 10 s sur le bouton volume pour redémarrer la tablette : un bouton Redémarrer apparaît maintenant dans la barre du haut du panneau Système, à côté de Régénérer. Comportement Tap → dialog de confirmation ("Toutes les apps en cours seront fermées") Confirme → reboot dispatché via ADB local (uid shell autorisé sur DiLink) Toast "Redémarrage en cours…", puis Android shutdown propre Pourquoi un dialog Le reboot tue toute la session voiture (HMI, GPS, audio…). Pas envie qu'un tap accidentel le déclenche. i18n 6 nouveaux strings dans les 12 locales (fr+en+de+es+it+ru+uk+be+kk+uz+tr+ar) LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.75-beta✨ Phase A Step 4 — Couche 1 : Triggers proactifs (BOOT + OTA) Ce que ça apporte Le daemon et le KeeperService sont réveillés avant que l'utilisateur ouvre DashCast. Trigger Quand Avant Maintenant BOOT_COMPLETED Allumage tablet pré-warm daemon + ProxyKeeperService.ensureRunning() MY_PACKAGE_REPLACED Install OTA DashCast rien full revive (daemon + Keeper) Pourquoi MY_PACKAGE_REPLACED Sans cet intent, après une mise à jour de DashCast le daemon restait mort jusqu'à ce que tu lances manuellement l'app. Désormais Android fire l'intent dès que l'install OTA est finie, le receiver remonte toute la pile proxy automatiquement. Récap de la défense en profondeur Couche Rôle Statut 3 — Daemon hardening OOM -900, PID lock JVM, self-heal ✅ v1.2.70 2 — KeeperService FG 24/7 Surveillance permanente 10s ✅ v1.2.73 1 — Triggers proactifs BOOT_COMPLETED, MY_PACKAGE_REPLACED ✅ v1.2.75 4 — UX recovery Cooldown adaptatif, notif ADB, métriques ⏭ v1.2.76 Compatibilité Aucune. Tout est gated sur BetaConfig.isProxyDaemonEnabled → zéro overhead si tu n'as pas activé le proxy daemon. Test Désinstalle puis réinstalle DashCast par-dessus, ou attends une OTA : le daemon doit être joignable immédiatement, sans ouvrir l'app. LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.74-beta🐛 Fix — "Miroir cluster actif" reste affiché après l'arrêt Symptôme Une notification permanente DashCast — Miroir cluster actif restait dans le shade Android même quand la projection cluster était arrêtée et le badge flottant 📺 invisible. Cause FloatingRemoteButton.hide() cachait juste la View overlay mais ne décrochait jamais le service de son état foreground → la notification restait collée tant que le process DashCast vivait. Fix hide() → stopForeground(STOP_FOREGROUND_REMOVE) : notif retirée show() → startForeground() re-promotion avec la même notif startForegroundCompat() au démarrage : si aucune projection active (sShouldBeVisible == false), drop FG immédiatement → pas de notif fantôme au lancement de l'app Compatibilité Aucune. Notification réapparaît automatiquement dès qu'une app est projetée sur le cluster. À noter La notification permanente DashCast — proxy actif (Couche 2 v1.2.73) reste affichée 24/7 quand le proxy daemon est activé — c'est normal et obligatoire (Android exige une notif pour un FG service). LinksAPK download GitHub release page
-
Navi on Dashboard - Free app to display navigation on the BYD instrument panel
@BydSy26pro What is your car model?
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.73-beta✨ Phase A Step 4 — Couche 2 : ProxyKeeperService 24/7 Surveillance permanente du daemon, même quand l'app est fermée. Ce que ça apporte Service foreground avec heartbeat toutes les 10 s sur le binder du daemon Si binder mort → reconnect proactif immédiat (cooldown 10s respecté) START_STICKY → Android relance le service après un OOM kill Notification permanente low-importance, sans son ni vibration (obligatoire pour un FG service) Tap notif → ouvre MainActivity Combiné avec Couche 3 (v1.2.70) Couche Rôle État 3 — Daemon hardening OOM -900, PID lock JVM, self-heal ✅ v1.2.70 2 — Keeper FG 24/7 Surveillance permanente 10s ✅ v1.2.73 1 — Triggers proactifs BOOT_COMPLETED, PACKAGE_REPLACED ⏭ v1.2.74 4 — UX recovery Notif ADB, métriques diag ⏭ v1.2.75 Nouveaux strings (12 locales) proxy_keeper_channel_name, proxy_keeper_channel_desc, proxy_keeper_notif_title, proxy_keeper_notif_text Prérequis Gated sur BetaConfig.isProxyDaemonEnabled — si tu n'as jamais activé le daemon dans les Settings, aucun service ni notification ne démarre. Installation Installer v1.2.73 par-dessus v1.2.72. Tu verras apparaître une notification permanente "DashCast — proxy actif" dans la barre. C'est normal et obligatoire (Android exige une notif pour les FG services). LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.72-betaDL5 Fission resize battery — refocused 7 scattered probes collapsed into 3 focused shots, with a novel "resize the STACK, not the task" avenue that has never been tried on DL5 before. Why refocus Field reports v1.2.59 / v1.2.60 / v1.2.61 proved the per-verb exploration approach had exhausted the obvious shell surface without finding a working path: set-task-windowing-mode → stripped on DL5 cmd activity task resize → silent no-op (exit=0, bounds unchanged) cmd window set-display-windowing-mode → stripped am start --activity-launch-bounds → unknown option Rather than add a 13th nano-probe we collapse the F10..F12E block into 3 sharp probes that go straight at the remaining hole. The 3 new probes (all via AdbLocalClient — DIAG rule) F10 — Topology. Captures taskId of the target app, the stackId hosting it (parsed from dumpsys activity activities), current mBounds mWindowingMode, plus a compact inventory of resize-relevant verbs (cmd activity stack, cmd activity task, am stack, wm). F11 — DL3 chain via shell. One atomic shell script: cmd activity task resizeable <taskId> 2 (unlock) Try every stack-resize verb (the novel part): am stack resize <stackId> 100 80 1820 640 cmd activity stack resize <stackId> 100 80 1820 640 cmd window stack resize <stackId> 100 80 1820 640 Retry cmd activity task resize <taskId> 100 80 1820 640 Dumpsys diff. Reports which verbs were accepted (accepted verbs: …). F12 — Verify final bounds. Confirms whether the rect stuck. Why this might finally work All prior probes targeted IActivityTaskManager.resizeTask(taskId, …) — the shell verb for which (cmd activity task resize) is silent no-op on DL5. The DL3 production code path actually calls IActivityTaskManager.resizeStack(stackId, Rect) — a different AIDL method on a different object. The shell verb for resizeStack has never been tried on DL5. If any of the 3 variants in F11 step 2 is honoured, we have a real shell resize path. Strictly additive F01..F09 + F13..F16 are byte-identical to v1.2.60-beta. SKIP outside DL5. No production runtime change. Net: 20 → 16 probes. Asset DashCast-v1.2.72-beta-debug.apk (signed bydPlatform). LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.71-betaDL5 Fission test — F12E probe (AdbLocalClient only) Field-driven follow-up to v1.2.60. The DL5 user-run log log/byd_report_20260528_172327.log confirmed that the 3 hypotheses tested in v1.2.60 (F12A/F12B/F12C) are all dead on this ROM, but F12A's verb inventory revealed cmd activity task resizeable <TASK_ID> [0|1|2|3] is still present in the binary — a fresh, never-tried avenue. Why DIAG stays 100% on AdbLocalClient The whole DL5 Fission battery (F01..F16) runs through AdbLocalClient only — never the daemon. An earlier draft added an F12D that called BetaProxyClient.moveAndResize (daemon-side AIDL reflection); it was removed before shipping because the daemon path is reserved for production runtime, not the in-app diagnostic surface. If the reflection path needs validation it will be probed from production code under a feature flag, not from DIAG. What's new F12E — shell task resizeable 2 then retry resize. Sets the task's resizeable mode to 2 (resizeable) via the still-present cmd activity task resizeable <taskId> 2, sleeps 1 s, retries cmd activity task resize <taskId> 100 80 1820 640, sleeps 2 s, dumpsys the bounds. Hypothesis: F11's silent no-op is caused by the task being in resizeable mode 0 at runtime. Strictly additive F01..F12C + F13..F16 are byte-identical to v1.2.60-beta. SKIP outside DL5. No production runtime change. Asset DashCast-v1.2.71-beta-debug.apk (signed bydPlatform). LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.70-beta✨ Phase A Step 4 — Couche 3 : daemon hardening Première couche de défense vers la disponibilité 100%. Tout côté daemon, zéro impact UX. Nouveautés OOM protection — le daemon écrit -900 dans /proc/self/oom_score_adj au démarrage. Le Linux Low-Memory Killer ira chercher les apps en foreground avant nous. PID lock atomique en JVM — remplace le flock shell cassé (cascade v1.2.63→v1.2.69). Au démarrage, lit dashcast_proxy.pid, vérifie que le PID est vivant ET que son /proc/PID/cmdline contient dashcast_proxy. Si oui → refuse de démarrer (le canonique reste seul). Fail-open sur erreur I/O. Self-heal heartbeat 10s — thread daemon qui : recrée le trigger file si supprimé réarme le FileObserver (perd son inode binding sur delete) se suicide si un autre daemon a volé le lock (survivor canonique) Compatibilité PROTOCOL_VERSION 7→8 (additif). Les anciens clients continuent de marcher. Prochaines étapes v1.2.71 → ForegroundService permanent (Couche 2) v1.2.72 → BOOT_COMPLETED + spawn proactif (Couche 1) v1.2.73 → UX recovery + métriques (Couche 4) LinksAPK download GitHub release page
-
BYD released Xuanji A3 ADAS chip as it aims at accident-free traffic
BYD released the new self-developed 4-nm Xuanji A3 assisted driving chip capable of L3 and L4 autonomous driving functions. The company kicked off mass production of this computing unit, underlining the long-term goal of accident-free traffic. During the launch event of the new chip, BYD chairman Wang Chuanfu shared that the company currently has over 7,000 people in its chip R&D team as well as a long-running semiconductor business. On May 28, BYD responded to the growing number of self-developed ADAS chips from other automakers, including the recent Mach 100 chip from Li Auto, Turing AI from Xpeng, and NX9031 from Nio. More about the Xuanji A3 chip The new Xuanji A3 is China’s first mass-produced 4-nm autonomous driving chip. BYD officials highlighted that this chip supports L3 and L4 driving solutions. The company will be able to integrate these computing units in upcoming robotaxi fleets. BYD shared that the Xuanji A3 chip boasts full-chain control over assisted driving, allowing integration of software and hardware. Despite BYD sharing a lot of exciting information, it is worth noting that the combination of three Xuanji A3 chips has a combined peak computing power of 2,100 TOPS. It means a single Xuanji A3 chip offers 700 TOPS of computing power. It is in line with the Nvidia Drive Thor. However, the Mach 100 chip from Li Auto delivers 1,280 TOPS. And the Xpeng’s Turing AI chip offers 750 TOPS. The BYD Xuanji A3 chip It means the Xuanji A3 chip isn’t the best in terms of computing power. However, BYD shared that its power utilization rate had increased by 100%, compared to previous chips. It will also be compatible with a thousand-line LiDAR sensor. Previously, BYD-backed Robosense revealed a sensor with up to 2,160 lines. The company’s thousand-line LiDARs will be adopted by L3- and L4-ready cars. It promises to be more precise than the current 896-line LiDAR from Huawei, widely adopted by cars under the HIMA umbrella. Wang Chuanfu added that BYD has a long-term goal of zero traffic accidents. He shared that every BYD car will be equipped with the DiPilot 300 (“God’s Eye B”) LiDAR-based assisted driving system. It will be available even for the entry-level models as a paid extra option worth 12,000 yuan (1,770 USD). With this step, BYD aims to enhance its domestic sales volume. According to China EV DataTracker, BYD delivered 156,944 units in April in China, down 19.8% Year-Over-Year.
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.69-beta🚑 HOTFIX #5 — drop the flock entirely v1.2.68 field logs confirm ALREADY_BOOTSTRAPPING ps= is still returned with an empty ps output, even with the command -v flock guard. So either: flock is present but mis-behaves on DiLink 3 (returns non-zero even with no other holder) exec 9>file silently fails (perms? mksh quirk?) After 6 hotfixes chasing this lock, just drop it. Race protection without flock Already covered three ways: 10s RECONNECT_COOLDOWN_MS in attemptReconnect — app side, no shell needed Stale-kill below — kills any duplicate before spawning ps fast-path above — short-circuits when a daemon is already alive Worst case: two near-simultaneous cold bootstraps spawn two daemons; the second one's stale-kill kills the first; only one survives. Acceptable. Install Install v1.2.69 over v1.2.68. No reboot needed — the daemon will finally actually spawn this time. LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.68-beta🚑 HOTFIX #4 — TRUE root cause: flock is not on DiLink 3 After 4 iterations chasing increasingly subtle PID-file detection bugs, the real culprit was much simpler: the flock binary doesn't exist on DiLink 3. It's part of util-linux, not toybox. What was happening if ! flock -n 9 2>/dev/null; then echo ALREADY_BOOTSTRAPPING; exit 0; fi When flock is missing, the command returns 127 (not-found), so ! flock is TRUE on EVERY call. Result: Every bootstrap immediately returned ALREADY_BOOTSTRAPPING The daemon was NEVER actually spawned since v1.2.63 The ps-based fast-path (v1.2.67) couldn't match either — no daemon to find App stuck forever in a 15s broadcast-timeout loop This single bug invalidated v1.2.63, v1.2.64, v1.2.65, v1.2.66 AND v1.2.67. Fix Gate the flock on its availability: HAS_FLOCK=0; command -v flock >/dev/null 2>&1 && HAS_FLOCK=1 if [ "$HAS_FLOCK" = "1" ]; then exec 9>...; flock -n 9 || exit; fi When flock is missing, just skip the lock. The stale-kill below already prevents duplicate daemons, so losing the bootstrap-level lock is acceptable degradation. Bonus: diagnostics ALREADY_BOOTSTRAPPING now includes the ps output (e.g. ALREADY_BOOTSTRAPPING ps=u0_a142 1234 ...) A [diag] no_alive ps_lines=N has_flock=0|1 line is emitted on stderr Install Install v1.2.68 over v1.2.67 — should fix the issue immediately, no reboot needed. The ps fast-path will pick up any v1.2.63+ stuck daemon through the trigger file. LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.67-beta🚑 HOTFIX #3 — abandons PID-file detection for the bulletproof ps heuristic Symptoms in v1.2.66: still ALREADY_BOOTSTRAPPING everywhere. Root cause: every iteration of the PID-file fast-path had a different subtle failure mode (PID file missing, /proc/comm = 'main', toybox grep -a unreliable). Field logs from v1.2.66 confirm the fast- path STILL never matched. Fix Drop the PID-file dependency entirely. Use EXACTLY the same heuristic as the stale-kill (proven in production since 1.1.5): ps -A | grep '[d]ashcast_proxy' | awk '{print $2}' If any live daemon is found — INCLUDING the v1.2.63/64/65/66 ones still stuck in the field with the FD-9 lock leak — we just touch the trigger file. The FileObserver introduced in v1.2.63 lives in ALL those daemons and will re-emit the binder broadcast. Result Recovery works without rebooting the tablet (the new fast-path reaches the stuck old daemons through the trigger file). Same heuristic as stale-kill → the two identity checks can no longer disagree. PID file is still written (useful for diagnostics) but no longer required. Install v1.2.67 over v1.2.66 — should fix the issue immediately, no reboot needed. LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.66-beta🚑 HOTFIX #2 — fast-path was reading the wrong /proc field Symptoms in v1.2.65: same as v1.2.63/64 — projection refuses to start, freezes, every bootstrap returns ALREADY_BOOTSTRAPPING. Root cause: v1.2.65's fast-path tested cat /proc/$PID/comm = dashcast_proxy to validate that the PID file pointed to our daemon. But /proc/PID/comm is the thread name — Android's app_process --nice-name sets argv[0] (visible in cmdline and ps) but the JVM keeps the main thread's comm as main. The fast-path therefore never matched even with a healthy daemon alive. Combined with the v1.2.63/64 daemon still holding FD 9 (unkilled in the field), every bootstrap fell through to flock → ALREADY_BOOTSTRAPPING → 15 s broadcast timeouts → fallbacks everywhere → freezes. Fix Replace the comm check with grep -aq dashcast_proxy /proc/$P/cmdline -a forces text mode (cmdline is NUL-separated) -q silent, returns 0/1 matches the same field used by the existing ps | grep stale-kill heuristic, so the two identity checks are now consistent. Applied identically to the Diag « Test rebroadcast » button. Recommandé en voiture Installer v1.2.66 par-dessus v1.2.65 (pas besoin de désinstaller). Si la projection reste cassée après install, un seul reboot tablette suffit (kills le vieux daemon v1.2.63/64/65 stuck) → ensuite v1.2.66 doit fonctionner normalement et le PID-file fast-path doit marcher pour tous les bootstraps suivants. LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.65-beta🚑 HOTFIX — v1.2.63 / v1.2.64 had a critical bootstrap regression Symptoms in v1.2.63 / v1.2.64: projection refusing to start, tablet freezes, every bootstrap call returns ALREADY_BOOTSTRAPPING even on cold boot, followed by no live binder after 15000ms. Root cause: the flock-based bootstrap script opened FD 9 to take an advisory lock, then spawned the daemon via setsid sh -c "..." & — without closing FD 9 in the child. The daemon inherited FD 9 and held the lock for its entire lifetime. Every subsequent bootstrap call then hit flock -n 9 → fail → ALREADY_BOOTSTRAPPING, never reaching the PID-file fast path. Auto-recovery broken, rebroadcast unreachable, 15 s broadcast timeouts on every reconnect, UI freezes when fired on the main thread. Fixes PID-file fast path moved BEFORE the flock. It's pure read + trigger-file touch, idempotent under concurrency — never needed the lock. This unblocks recovery for users with a v1.2.63 / v1.2.64 daemon currently stuck in the field (the fast-path bypasses the lock those daemons still hold until next reboot/kill). 9>&- added to the setsid spawn so the daemon explicitly closes FD 9 before exec app_process64. Future bootstraps see a free lock; the flock guard works as designed (concurrent cold-start storm protection only). Zero new code paths — same script, just reordered + one FD close. Recommandé Installer v1.2.65 par-dessus v1.2.64 directement (l'ancien daemon reste utilisable via la fast-path). Si problèmes persistent : reboot tablette pour killer les vieux daemons stuck (1.2.63 / 1.2.64). LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.64-betaExport daemon log (Telegram) — in-car post-mortem Adds a « 📥 Export daemon log (Telegram) » button in Diag → Cluster POC. Reads /data/local/tmp/dashcast_proxy.log via AdbLocalClient (uid=2000 shell owns the file → works even when the daemon is dead). Prepends a state header: PID / lock / trigger file status + alive dashcast_proxy processes. Caps the log tail at 200 KB (Telegram-friendly). Writes to app cache + shares via the FileProvider chooser. No more adb pull needed for in-car incident reports. Includes all v1.2.63-beta changes (Phase A step 3: PID-file + flock + trigger-file rebroadcast). LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.63-betaPhase A step 3 — PID-file + flock + trigger-file rebroadcast Builds on step 1 (auto-recovery) + step 2 (foreground watchdog). The daemon now writes its PID to a known path and watches a trigger file; the bootstrap script's fast path can ask a surviving daemon to re-emit its binder in milliseconds, instead of paying the ~1 s app_process restart cost after every app restart. Daemon (ProxyDaemonMain) Writes its PID to /data/local/tmp/dashcast_proxy.pid at startup. Watches /data/local/tmp/dashcast_proxy.trigger via FileObserver and re-emits ACTION_PROXY_CONNECTED on any touch. Best-effort shutdown hook cleans PID + trigger files. Extracted emitBroadcast() so the trigger path and the cold-boot path go through the exact same code. PROTOCOL_VERSION 6 → 7 (purely additive, old clients still work). App (BetaProxyClient.BOOTSTRAP_CMD) Atomic via flock -n on /data/local/tmp/dashcast_proxy.lock — concurrent bootstrap invocations now serialize at the shell level (belt-and-suspenders on top of the 10 s Java cooldown from step 1). PID-file fast path: if a daemon is already alive and its /proc/<pid>/comm is dashcast_proxy, the script just touches the trigger file and exits with REBROADCAST <pid>. Skips the entire app_process + systemMain + broadcast chain. Silent fallback to the legacy full bootstrap when the PID file is missing/stale or flock is unavailable — zero regression. Diag (Cluster POC panel) New « 📡 Test rebroadcast (fast-path) » button: reproduces the fast-path shell branch and reports the round-trip time. Expect < 200 ms with REBROADCAST <pid> in the output. In-car test plan Smoke — boot, cluster mirror, resize, force-stop unchanged vs v1.2.62. Watchdog status — installed + connected + non-zero PID. NEW — Test rebroadcast — tap the button, expect ✅ and < 200 ms. Verify PID file — adb shell cat /data/local/tmp/dashcast_proxy.pid must match the PID shown by Watchdog status. Cross-restart fast path — kill the app (swipe from recents), reopen, open Diag and tap any wrapped verb (Recovery test, etc.). Reconnect should be noticeably faster than v1.2.62 (no app_process respawn). LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.62-betaPre-release for in-car testing. Phase A step 2 — proactive liveness ping for the proxy daemon. A new ProxyWatchdog singleton, installed at app boot, polls BetaProxyClient.isConnected() every 30 s while the app is in the foreground. When the binder is dead it triggers a silent connect() so the next user-initiated typed verb is instant instead of paying the ~1 s bootstrap cost on its first call (as observed in v1.2.61-beta tests). Design Polling only while at least one activity is resumed (registerActivityLifecycleCallbacks, zero new deps). Stops as soon as the last activity pauses → zero background drain. Gated on BetaConfig.isProxyDaemonEnabled → users who never opted in pay strictly zero overhead. Reconnect path reuses the same 10 s cooldown gate inside connect() → bootstrap cascades remain impossible. Tick body is try/catch wrapped on a dedicated HandlerThread → can never crash the app. Cost when daemon is healthy One volatile read + one isBinderAlive() (~5 µs) every 30 s. Invisible. In-car test plan Smoke test — boot normally, exercise cluster mirror / resize / force-stop. Must be visually identical to v1.2.61-beta. Watchdog status — Diag → Cluster POC panel → new button 🐕 Watchdog status. Should show installed=true foreground≥1 proxyEnabled=true connected=true pid=…. Proactive recovery — same panel: tap 💀 Kill daemon (pid disappears), wait 30–40 s without touching the app, retap 🐕 Watchdog status → pid must have changed (new daemon, brought up by the watchdog, not by you). Optional: redo 🩺 Test recovery after step 3 — should now report elapsed ≈ 0 ms since the daemon was already up. Logcat tag: ProxyWatchdog (one info line on install, one info line per proactive reconnect). Branch: phase-A-proxy-recovery — still not merged into main, beta/1.2.0-dilink5 untouched. LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.61-betaPre-release for in-car testing. Adds three buttons in Diag → Cluster Move/Resize panel, right under the existing 🔄 Restart daemon row, so the v1.2.58-beta Phase A step 1 auto-recovery can be validated directly from the car — no ADB required. New buttons 💀 Kill daemon — SIGKILLs dashcast_proxy via dadb and shows the new isConnected state. Then trigger any normal diag action (Lister displays, Lancer, Apply…) and watch the auto-bootstrap kick in silently. 🩺 Test recovery — kill + immediate typed-verb probe (getPidsByPackage). Reports oldPid → newPid, elapsed ms and PROTOCOL_VERSION. This is the golden-path validation. 🌪 Anti-storm test — (kill → probe) ×3 in <1 s. Expected: cycle 1 reconnects (5–8 s), cycles 2 and 3 are cooldown-blocked (10 s gate), proving the bootstrap-cascade protection works. Kill is always routed through AdbLocalClient (dadb), never through the wrapped BetaProxyClient.runShell, so auto-recovery can't race the kill. In-car test plan (Telegram copy-paste below) Smoke test — boot, enable cluster mirror, resize SeekBar, force-stop a mirror, switch YouTube ↔ cluster. Must be visually identical to v1.2.57-beta. 🩺 Test recovery — should show ✅, newPid different from oldPid, elapsed ~5000–8000 ms, proto ≥ 5. 🌪 Anti-storm test — cycle 1 ✅, cycles 2 and 3 ⏸ "cooldown blocked". Optional: 💀 Kill daemon then press "📋 Lister displays" → must succeed silently after a short delay. If anything is unexpected, share the report (📤 Partager rapport) and the logcat tag BetaProxyClient. Branch: phase-A-proxy-recovery — still not merged into main, beta/1.2.0-dilink5 untouched. LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.60-betaPre-release for in-car testing. Not merged into main. Branch: phase-A-proxy-recovery. This release bundles three beta increments since v1.2.57-beta. None of them changes behaviour on DL2 / DL3 / DL4 — all DL5-specific work is gated by the existing platform auto-detection. v1.2.60-beta (vc320) — DL5 Fission test: 3 new exploration probes (F12A / F12B / F12C) Pure additive rows inserted between F12 and F13 in the Fission live-test battery. F01..F12 + F13..F16 behave byte-identical to v1.2.59-beta — if a tester re-runs the suite the existing rows look exactly the same, the 3 new rows just give us more data. On any platform other than DL5 the 3 new rows SKIP via the existing outer DL5 gate. The goal of the 3 probes is to find a real DL5 resize path despite the stripped cmd activity verbs that v1.2.59-beta documented. F12A — verb-surface inventory. Pure read-only. Runs cmd activity (no-arg help) + cmd activity task + cmd window + a focused am help grep. Reports a one-line summary: am task resize=Y/N, set-task-windowing-mode=Y/N, cmd window set-display-windowing-mode=Y/N Authoritative inventory of what survived the BYD strip — no more guessing which subverb to try next. F12B — display windowing mode → freeform, retry resize, auto-revert. Sequence: cmd window set-display-windowing-mode <confirmedClusterDisplay> freeform sleep 1 s cmd activity task resize <taskId> 100 80 1820 640 sleep 2 s dumpsys mBounds for the task revert the display back to fullscreen so the cluster face is left exactly as F12 saw it. PASS = BREAKTHROUGH — display freeform unlocked task resize. Tests the hypothesis that the silent no-op of F11 in v1.2.59 was caused by the fission display declaring mDisplayWindowingMode=fullscreen, and that forcing the display itself into freeform is the missing piece. F12C — launch-time bounds via --activity-launch-bounds. Sequence: am force-stop <targetPkg> am start --display <id> --windowingMode 5 --activity-launch-bounds 100,80,1820,640 -n <component> sleep 3 s dumpsys mBounds PASS = BREAKTHROUGH — launch-time bounds honoured on cluster display. Tests whether DL5 honours launch-time bounds where post-launch resize is a no-op; if so, the production resize path becomes "tear down + relaunch at new rect" rather than mutating an existing task. WARN-on-unknown option so the row's message is self-explanatory. Safety / reversibility: F12B's only mutation (display windowing mode) is reverted in the same shell pipeline before the row returns. F12C's only mutation (re-launched activity) is cleaned up by the existing F14 force-stop two rows later. Touched files. app/build.gradle (319 → 320, 1.2.59-beta → 1.2.60-beta), dilink5/Dl5ClusterReconRunner.java (+3 TestDef entries, +3 switch arms in runFissionOne, +3 private implementations, +1 tokenForPkg busybox-safe grep-token helper), CHANGELOG.md. No new strings — no i18n surface touched. v1.2.59-beta (vc319) — DL5 cluster resize disabled at the UI when the ROM ships a stripped cmd activity binary Field-validated workaround. Source: log/byd_report_20260528_081206.log (BYD DiLink 5.0 / Android 12 / build SKQ1.230128.001, user-run Fission live tests). The report confirms the launch pipeline works end-to-end on DL5 — F01 PASS (service call auto_container 2 i32 1000 i32 16 opens the cluster projection), F04 + F05 PASS (am start --display 2 --windowingMode 5 -n ru.yandex.yandexnavi/.core.NavigatorActivity lands Yandex Navi fullscreen on the cluster face, user-confirmed visually), F13..F16 PASS (move-back-to-display-0 + sendInfo 18+0 cleanup chain works). But the report also proves resize is a ROM-level no-op on this build: F10 WARN — cmd activity set-task-windowing-mode → Unknown command: + exit=255 (verb stripped from the binary). F11 PASS-but-no-op — cmd activity task resize 76 100 80 1820 640 returns exit=0 with zero visible effect. F12 WARN — post-resize dumpsys shows mBounds=Rect(0, 0 - 1920, 720) mWindowingMode=fullscreen mMagicWindowMode=MAGIC_MODE_FULLSCREEN (bounds unchanged). That's the same outcome the in-app ClusterService.resizeActiveTask reflection-then-shell cascade was producing on every SeekBar drag since v1.2.26 — silently doing nothing while looking like it worked. Fix — strictly additive, fully reversible, DL2/DL3/DL4 unchanged. Platform.isClusterTaskResizeSupported(ctx) — new lazy capability probe. On DL5 it forks one sh -c "cmd activity set-task-windowing-mode 2>&1" with a 1.5 s timeout on a daemon thread and caches the result both in a volatile field and a sticky SharedPreferences key (platform_cluster_resize_supported = "yes" | "no"). Conservative: any error or ambiguous output → "supported" (UX never downgrades on uncertain signal). On DL2/DL3/DL4 the method short-circuits to true immediately — no probe, no behavioural change on those platforms. DashCastApp.onCreate primes the probe at startup via Platform.primeClusterResizeProbe(this) so UI reads return the cached answer instantly without forking on the main thread. ClusterService.resizeActiveTask short-circuits at entry when !isClusterTaskResizeSupported(this), logs once via the new static sResizeUnsupportedLogged gate, and returns without running the IATM-then-shell cascade — saves ~30 useless verbs per SeekBar drag. MainActivity hides btn_toggle_resize + panel_resize on DL5 when the probe returned "no", so the user never sees a broken affordance. No new strings. Reversibility. When a future BYD ROM update restores the verb, wiping the SharedPreferences key re-enables the SeekBar with zero code change. Docs. New doc_api/DL5_CLUSTER_RESIZE_LIMITATION.md with the full F10/F11/F12 verbatim plus three RE-able avenues for an actual DL5 resize. v1.2.58-beta (vc318) — Phase A step 1: daemon auto-recovery in BetaProxyClient typed verbs When the proxy daemon dies (OOM kill, manual kill -9, etc.), production typed verbs now silently bootstrap a fresh daemon, gated by a 10 s cooldown (anti-storm). When the daemon is healthy, behaviour is byte-identical to v1.2.57-beta. Wrapped verbs (production hot path + cluster ops): runShell, setOverscan, getPidsByPackage, autoContainerSendInfo, forceStopPackage, releaseVirtualDisplay, launchAndForce, moveAndResize, cleanFissionStacks. Intentionally not wrapped: ping, runPhase4Probes (health / diag — retry would mask failures), create* (unchanged). In-car test plan for v1.2.60-beta Smoke test (any platform). Boot normally → enable cluster mirror, force-stop a mirror, switch YouTube → cluster. Must behave exactly as v1.2.57-beta, no visible regression. Resize SeekBar: visible on DL2/DL3/DL4, hidden on DL5 (workaround from v1.2.59). DL5 Fission probe (NEW — primary objective of this release). Open Diag → run Fission live tests with any installed launchable target (2GIS, Yandex Navi, Maps…). Watch the new rows: F12A always passes (it's read-only) — copy its msg line, it tells us which verbs survived. F12B PASS = breakthrough on the "display freeform" hypothesis. F12C PASS = breakthrough on the "launch-time bounds" hypothesis. Both WARN = report stays useful, we'll design the next probe based on F12A's inventory + F12B/F12C raw output. Daemon auto-recovery sanity (carried over from v1.2.58). adb shell pgrep -f dashcast_proxy adb shell kill -9 <pid> then trigger any cluster action. Must succeed silently with a single info log line: attemptReconnect: bootstrapping daemon (cooldown gate passed) followed by daemon ready (uid=2000 pid=…). Logs to collect. Send the full Fission report via the existing "Send via Telegram" button + logcat tags BetaProxyClient, Dl5ClusterRecon, plus any WARN/ERROR. LinksAPK download GitHub release page
-
DashCast — BYD Cluster Launcher & Mirror
DashCast v1.2.58-beta-phase-A-step1Pre-release for in-car testing. Phase A step 1 — daemon auto-recovery in BetaProxyClient typed verbs. When the proxy daemon dies (OOM kill, manual kill -9, etc.), production typed verbs now silently bootstrap a fresh one with a 10s cooldown gate (anti-storm). Behaviour when the daemon is healthy is byte-identical to v1.2.57-beta. In-car test plan Smoke test: boot normally → enable cluster mirror, resize via SeekBar, force-stop a mirror, switch YouTube → cluster. Must behave exactly as before, no visible regression. Auto-recovery: from ADB: adb shell pgrep -f dashcast_proxy adb shell kill -9 <pid> then trigger any cluster action (resize or force-stop). Must succeed silently with a single info log line: attemptReconnect: bootstrapping daemon (cooldown gate passed) followed by daemon ready (uid=2000 pid=…). Logs to collect: logcat tag BetaProxyClient plus any WARN. Wrapped verbs (production hot path + cluster ops) runShell, setOverscan, getPidsByPackage, autoContainerSendInfo, forceStopPackage, releaseVirtualDisplay, launchAndForce, moveAndResize, cleanFissionStacks. Intentionally not wrapped ping, runPhase4Probes (health/diag, retry would mask failures), createVirtualDisplay (Surface lifecycle owned by caller). Zero-regression guarantees Daemon healthy → identical path, overhead = one volatile read. Daemon dead, reconnect OK → silent recovery, single info log line. Daemon dead, reconnect fails or cooldown-gated → throws BetaProxyException exactly like before → callers still fall back to legacy AdbLocalClient.executeShell*. Branch: phase-A-proxy-recovery — not merged into main, beta/1.2.0-dilink5 untouched. LinksAPK download GitHub release page
-
BYD’s first flash-charging model, Denza Z9 GT, surpasses 10,000 deliveries in 2.5 months
Denza, a premium brand under BYD, announced today that its Z9 GT has officially surpassed 10,000 cumulative deliveries. The vehicle was first launched in China on March 5th and then in Europe on April 9th. This delivery milestone comes just two and a half months after the vehicle first began reaching customers on March 13. The Z9 GT, which starts at 269,800 yuan (39,700 USD), is the world’s first mass-produced vehicle to feature BYD’s second-generation Blade Battery and flash-charging technology. The model is available in both pure electric (BEV) and plug-in hybrid (PHEV) configurations, with pricing ranging up to 369,800 yuan (54,400 USD) in China. Performance The vehicle’s rapid charging capabilities are a standout feature, largely attributed to the second-generation Blade Battery, which boasts an increased energy density of 190–210 Wh/kg, supported by a comprehensive thermal management system. In standard temperature conditions, the Z9 GT can charge from 10% to 70% in 5 minutes, and reach 97% in 9 minutes. In extreme cold – down to -30°C – charging from 20% to 97% takes 12 minutes. In terms of range, the pure electric version offers a maximum CLTC range of 1,036 km. The PHEV variant provides a pure electric range of 401 km and a combined range of 1,301 km. Denza celebrated the milestone on social media. Technology and Design Built on BYD’s “e3” (Yi San Fang) intelligent vehicle control platform, the pure electric trim delivers a total power output of 850 kW (1,140 hp) and a peak torque of 1,210 N·m, enabling a 0–100 km/h acceleration time of 2.7 seconds. The vehicle also features a minimum turning radius of 4.62 meters, the “God’s Eye” 5.0 intelligent driving system, and the DiSus-A intelligent air body control system. The Z9 GT’s design features a sleek, aerodynamic profile with a “Z”-shaped side trim and an integrated floating rear spoiler. Inside, the cabin is equipped with zero-gravity seats for the front passenger, a smart refrigerator, and an AR-HUD system, all complemented by a new “Lava Red” interior colour option. Global sales performance of the Denza brand. Following the launch of the Denza Z9 GT in early March, the Denza brand’s global sales reached 7,133 units in March this year, a month-on-month increase of 29.7%, and 11,250 units in April, up 57.7% from the previous month.