Files
language-installer/AGENTS.md
T
2026-06-11 03:57:37 +08:00

15 KiB

长安语言刷入工具 (Changan Language Flashing Tool)

Overview

Windows GUI tool suite (Python 3.6+ / tkinter) for flashing or pushing multi-language APKs to Android-based vehicle infotainment systems. Built by 宜宾科宜科技有限公司.

Most tools are single-file tkinter apps with the same rough architecture: GUI, VIN authorization, package extraction, ADB commands, logging, and worker threads live in one class. Preserve that style unless the user explicitly asks for a larger refactor.

Tool Variants

Tool file Vehicle / purpose Window title Pack script
Q07/app.py 启源Q07 长安语言安装工具 Q07/pack_q07.bat
S05/S05.py 深蓝S05 original 深蓝S05多语言安装 S05/pack_s05.bat
S05/S05_fixed.py 深蓝S05 fixed/experimental copy 长安语言安装工具 S05/pack_s05_fixed.bat
X5plus/X5plusTool.py X5plus 适用于X5plus多语言安装 X5plus/pack_x5plus.bat
Yidong/app-install.py 长安逸动通用 长安语言刷入工具 Yidong/pack_common.bat
Yidong/app-yidong.py 长安逸动 长安逸动语言刷入工具 Yidong/pack_yidong.bat
UNIZ/UNIZ.py UNI-Z file pusher UNI-Z语言文件推送工具 UNIZ/pack_uniz.bat
Mazda-EZ60/Mazda-EZ60.py Mazda-EZ60 OS 1.2 Mazda-EZ60_OS-1.2适用 Mazda-EZ60/pack_mazda_ez60.bat
Q05-Lidar/Q05-Lidar_Installer.py Q05_Lidar permission/bootstrap + language installer Q05_Lidar Q05-Lidar/pack_q05_lidar.bat

Project Structure

├── Q07/                   # Q07 script, pack scripts, ignored build outputs
├── S05/                   # S05 original and fixed copy
├── X5plus/                # X5plus tool
├── Yidong/                # common/yidong tools
├── UNIZ/                  # UNI-Z file pusher
├── Mazda-EZ60/            # Mazda-EZ60 tool
├── A07/                   # Qiyuan A07 tool
├── Q05-Lidar/             # Q05_Lidar tool plus resource.dat/tools
├── app.ico
├── package.bin            # encrypted package, not committed; shared from root
└── tools/                 # shared adb/fastboot/7za dependencies for pack scripts
    ├── adb.exe
    ├── AdbWinApi.dll
    ├── AdbWinUsbApi.dll
    ├── fastboot.exe
    └── 7za.exe            # 7-Zip Extra 26.01, bundled by pack scripts

Architecture Notes

  • Most tools use class ADKAPKGUI; UNIZ/UNIZ.py uses UNIZLanguageGUI.
  • Worker actions run in threading.Thread(..., daemon=True).
  • Tkinter calls from workers must go through run_on_ui_thread(...).
  • Prefer self.root.after(0, lambda: func(*args, **kwargs)) in run_on_ui_thread; direct after(0, func, *args, **kwargs) breaks when kwargs such as text= or fg= are passed.
  • Background messagebox.* calls should be scheduled with run_on_ui_thread.
  • Keep files UTF-8 with # -*- coding: utf-8 -*-.

ADB And Auth

  • run_adb_command(command) handles normal ADB commands such as adb devices, adb push, and non-shell install calls.
  • run_adb_shell(shell_command) exists in the 逸动-family tools and Mazda copy; it shells into the device and automatically sends password adb36987.
  • All adb shell operations in Yidong/app-install.py, Yidong/app-yidong.py, and Mazda-EZ60/Mazda-EZ60.py should go through run_adb_shell().
  • UNIZ/UNIZ.py must not use adb shell; it only checks devices and pushes APKs to /storage/emulated/0/Download/.
  • Standard auth flow uses:
    • auth-check?vin=... for authorization.
    • package-key?vin=... for package.bin extraction password.
  • VIN keys:
    • Q07/S05/X5plus: ca_vin_info or VIN.
    • 逸动/Mazda: settings get system ca.car.vin via auto-password shell.
    • UNI-Z: user manually enters VIN.

Package Extraction

  • package.bin is extracted under %LOCALAPPDATA%\.cache\system\.android\....
  • Current cache directories:
    • Q07/app.py -> apps_cache_Q07
    • S05/S05.py / S05/S05_fixed.py -> apps_cache_S05
    • X5plus/X5plusTool.py -> apps_cache_X5plus
    • Yidong/app-install.py -> apps_cache_common
    • Yidong/app-yidong.py -> apps_cache_yidong
    • UNIZ/UNIZ.py -> apps_cache_UNIZ
    • Mazda-EZ60/Mazda-EZ60.py -> apps_cache_Mazda_EZ60
  • Shared binaries are managed under root tools/: adb.exe, AdbWinApi.dll, AdbWinUsbApi.dll, fastboot.exe, and 7za.exe. Vehicle pack scripts in subfolders should copy from %ROOT%\tools, not from each vehicle folder.
  • For progress display, detect support for -bsp1 by checking for -bs{o|e|p} in 7za help output.
  • If Incorrect command line appears, retry with the basic compatible command: x package.bin -pPASSWORD -oDIR -y.
  • Decode 7za output with GBK first, then UTF-8 fallback.
  • 7za progress must parse streamed output cumulatively. Do not read one byte and regex that single byte; percentages such as 42% span multiple bytes and will otherwise jump from 0 to 100.
  • User-facing resource extraction text should say 资源准备中 / Preparing resources, not 资源解压 / Extracting package, unless the UI is an explicit debug test.
  • Cache cleanup should be best effort in three places when feasible: before a new extraction, during normal window close, and via atexit for ordinary process exit. A forced process kill cannot be guaranteed, so also clear stale caches at next extraction/startup.

Shared UX And Safety Rules

  • Hosts update logic should replace conflicting entries for the managed domain. If the hosts file already contains the target domain with a different IP, delete that line and write the expected IP domain entry instead of appending duplicates.
  • VIN authorization logs should be explicit for operator-facing flows: print the current VIN, print data.vehicleName when auth-check returns it, print authorization success, and print a clear unauthorized/failure log when denied.
  • package-key requests should use the vehicle name returned by auth-check (data.vehicleName) whenever available. Do not hardcode a model name if the authorization API already returned the exact vehicle name for the VIN.
  • Normal users should not see low-level sensitive process details such as fastboot, init_boot, boot keys, or image names during permission/bootstrap flows. Use black-box text such as 正在获取权限中, 获取成功, and 获取失败; leave command details for debug mode only.
  • Process logs should stay minimal in normal mode. Detailed ADB/7za/API command logs belong behind debug mode.
  • All Tkinter UI updates and messagebox.* calls from workers must go through run_on_ui_thread(...).

Model-Specific Behavior

S05

  • Keep S05/S05.py as original unless explicitly asked.
  • Use S05/S05_fixed.py for experimental/fixed S05 changes.
  • Do not add chmod, chown, or restorecon to the S05 system-app push path unless explicitly requested; the target system inherits permissions.
  • S05/S05_fixed.py includes debug extract test Ctrl+Shift+E and 7za progress support.

UNI-Z

  • Endpoint for visible passwords: /api/authorizations/get-uni-z-pwd.
  • Display factoryPwd as factory mode password and password as debug password.
  • If authorized == false or password is empty, show unauthorized state and do not proceed.
  • password from get-uni-z-pwd is not the package extraction password.
  • Before push, call /api/authorizations/package-key?vin=... to get the real package.bin password.
  • Push only to /storage/emulated/0/Download/; no adb shell.
  • Language selection: RU/FR/ES/EN. Only the selected language Settings APK is pushed; other language Settings APKs are skipped silently.
  • Hidden debug mode: Ctrl+Shift+D, password zxch5200, logs full ADB/7za/API details.

Mazda-EZ60

  • Based on Yidong/app-install.py / 逸动 flow.
  • Uses auto-password shell (adb36987) for VIN reads, pm install, overlay enable, disable commands, settings, and reboot.
  • Installs APKs from extracted apps via push to /data/local/tmp then pm install -r -d.
  • Mazda-EZ60/Mazda-EZ60.py should show 7za extraction progress with stream parsing.
  • Regardless of APK install failures, run post-install configuration after the install loop.
  • Post-install overlays to enable:
    • com.tinnove.launcher.overlay
    • com.tinnove.scenemode.overlay
    • com.incall.dvr.overlay
  • Post-install packages to disable:
    • com.carinno.p1
    • com.wtcl.electronicdirections
    • com.ximalaya.ting.android.car
    • com.tinnove.netease.music
    • com.migu.miguplay.car
    • cn.cmvideo.car.play
    • com.tinnove.carshow
    • com.tinnove.changba
    • com.qiyi.video.iv
  • User cancelled the Ctrl+Shift+E direct extract test request for Mazda; do not add it unless asked again.

Q05_Lidar

  • This is the Q05_Lidar-specific tool and must not be confused with any ordinary Q05 variant or package.
  • Based on the shared installer visual style, but its resource structure and flashing flow are Q05_Lidar-specific.
  • The first-row 获取权限 button installs runtime.dat -> base.apk, reboots to fastboot, waits for a real fastboot devices row like <serial> fastboot with a non-aggressive interval, then fetches a boot key through POST /api/authorizations/boot-challenge then POST /api/authorizations/boot-key, decrypts embedded resource.dat, flashes init_boot, immediately reboots, and deletes the temporary img. Keep the decrypted img lifetime as short as possible.
  • resource.dat is AES-GCM encrypted and must match the server BOOT_KEY; the tool only accepts data.sessionKey from boot-key.
  • Device fingerprint data sent to the server includes ADB serial, ro.serialno, ro.boot.serialno, manufacturer, model, device, build fingerprint, and VIN.
  • 刷入语言包 installs Magisk modules, not APKs. It opens com.topjohnwu.magisk, warns the user to grant Shell/root permission, verifies /debug_ramdisk/su -c "id" returns uid=0, extracts Q05_Lidar-package.bin, then pushes module files to /data/local/tmp/q05_lidar_modules/<MODID>/ and root-copies them into /data/adb/modules/<MODID>.
  • Q05_Lidar-package.bin should unpack with module files at archive root: module.prop, scripts, system/, and disable-wireless-adb-vecentek-magisk.zip; do not wrap them in an outer Q05_LIDAR_DATA/ directory.
  • Q05_Lidar package cache is %LOCALAPPDATA%\.cache\system\.android\apps_cache_Q05_Lidar; the tool cleans it on startup/extraction and on normal/atexit shutdown.
  • Q05_Lidar runtime.dat cache is %LOCALAPPDATA%\.cache\system\.android\apps_cache_q05_lidar_runtime; treat it as temporary and clean stale contents before extraction.
  • Q05_Lidar-package.bin is an external release file next to the exe because it is large. resource.dat is embedded in the exe; runtime.dat should be copied next to the exe by the pack script.
  • package-key must include the vehicleName returned by auth-check for the VIN. The tool caches data.vehicleName from password query / authorization check and uses it for package-key; if missing, query auth-check first rather than falling back to a hardcoded Q05_Lidar value.
  • All adb shell commands in Q05_Lidar, including Magisk launch and /debug_ramdisk/su -c ..., must go through run_adb_shell() so the tool silently sends adb36987.
  • The 安装App button remains the APK install path: file picker -> adb push -> setprop vecentek.model 1 -> pm install -r -d -f -> cleanup. Do not replace it with the Magisk module flow.
  • Temporary debug mode exists only for development and should be removed before release when requested. Press Ctrl+Shift+D; the password is verified through POST /api/authorizations/verify-debug-mode-password.
  • In Q05_Lidar debug mode, hidden buttons appear for:
    • 指纹测试: collect and log device fingerprint fields plus local SHA256 summary.
    • 解密测试: if VIN/device is available, fetch boot key; otherwise prompt for a pasted BOOT_KEY/sessionKey, decrypt resource.dat locally to a temporary img, log size/SHA256, then delete it.
    • 解压测试: fetch package-key, extract Q05_Lidar-package.bin, and verify the main Magisk module plus disable_wireless_adb_vecentek module can be identified.
  • Do not log the actual boot key/session key in debug mode.

Yidong/app-yidong.py

  • Uses apps_cache_yidong.
  • Has 7za compatibility handling for progress switches and Incorrect command line fallback.
  • Yidong/pack_yidong.bat output name is ASCII: Changan-Yidong-Language-Installer.exe, to avoid CMD codepage issues with Chinese NAME.

Build Notes

  • Pack scripts install/use pyinstaller, cython, and usually pyzipper.
  • Cython success requires Microsoft C++ Build Tools.
  • Cython success signs in logs:
    • building '_core' extension
    • _core.cpXXX-win_amd64.pyd
    • PYD: _core...pyd
    • output under dist_cy\dist\...exe
  • If logs show [WARN] Cython failed, fallback and [INFO] Normal PyInstaller, the exe still builds but is normal PyInstaller and easier to reverse.
  • For security-sensitive tools like Q05_Lidar, do not keep a normal PyInstaller fallback. If Cython fails or no _core*.pyd is generated, stop the build and show an error.
  • A Cython onefile PyInstaller build should use a tiny launcher.py that imports main from compiled _core.pyd, and the exe archive should contain _core*.pyd. Confirm with PyInstaller archive viewer when in doubt.
  • UNIZ/pack_uniz.bat and Mazda-EZ60/pack_mazda_ez60.bat use ASCII output names to avoid CMD encoding problems.
  • Generated .exe, .spec, build/, dist/, and dist_cy/ are build artifacts and should not be committed unless explicitly requested.

Key Behaviors To Preserve

  1. Keep original tools untouched when a fixed or model-specific copy exists.
  2. Preserve VIN-based authorization for normal flashing tools.
  3. Fetch package-key from the server instead of hardcoding package passwords.
  4. Keep all shell commands in 逸动/Mazda tools behind run_adb_shell().
  5. Keep UNI-Z shell-free.
  6. Use run_on_ui_thread() for all tkinter UI updates from worker threads.
  7. Keep shared Android/7za binaries under root tools/ and have pack scripts copy from there.

Current Local State (2026-05-28)

  • UNIZ/UNIZ.py and UNIZ/pack_uniz.bat exist locally. Cython build has succeeded after installing Microsoft C++ Build Tools, producing dist_cy\dist\UNIZ-Language-Pusher.exe.
  • Mazda-EZ60/Mazda-EZ60.py and Mazda-EZ60/pack_mazda_ez60.bat exist locally. Mazda has 7za progress extraction, unconditional post-install configuration, three overlay enables, and nine package disables.
  • Yidong/app-yidong.py has been updated for 7za progress compatibility and Incorrect command line fallback.
  • Yidong/pack_yidong.bat has been updated with quoted paths, cd /d "%~dp0", and ASCII output name.
  • .gitignore has been expanded to ignore generated exe/spec artifacts.
  • There may be untracked local build outputs and generated specs; inspect git status --ignored before committing.

Known Issues

  • Some older tools still have minimal exception handling and bare except: pass.
  • test_extract.py hardcodes a password and should not be treated as production flow.
  • on_disable_upgrade behavior is Windows/vehicle specific.
  • Pure PyInstaller fallback is easy to reverse; prefer successful Cython builds for release.