Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<!-- README.md and README.en.md match section by section: if you change one, change the other in the same PR. -->

The management program for [ModAVD](https://github.com/ModAVD/ModAVD): the graphical manager `ModAVD.exe`, and the CLI and MCP server `modavd.exe`. Written in Go, standard library only. It currently supports Windows x64 only; the platform-specific parts are already split into a platform layer. For the plans for other platforms, see [ModAVD#27](https://github.com/ModAVD/ModAVD/issues/27).
The management program for [ModAVD](https://github.com/ModAVD/ModAVD): the graphical manager `ModAVD.exe`, and the CLI and MCP server `modavd.exe`. Written in Go, standard library only. The CLI and MCP currently support Windows x64 and Apple Silicon macOS; the graphical manager remains Windows x64 only. The platform-specific parts are already split into a platform layer. For the plans for other platforms, see [ModAVD#27](https://github.com/ModAVD/ModAVD/issues/27).

> **Version note (`main` and Releases)**: This document describes the implementation on the repository's `main`. `main` is currently at version `0.3.0`, the latest standalone Release is `v0.1.0` (matching ModAVD `0.36.0`), and `v0.2.0` has been drafted but not published. The background initialization on create, the `update` command and exit code 9, all new in `0.2.0`, are not in the `v0.1.0` download package. If you use a published package, go by the notes of the matching Release and the version inside the package.

Expand All @@ -22,7 +22,7 @@ Usage instructions and guidance for contributing are on the ModAVD documentation

## What this is

- ModAVD is an Android emulator based on the AOSP Android Emulator plus a set of patches. It supports Windows today, and more platforms are planned. This repository holds the programs that manage it: create, change and delete instances; start and shut down; the computer check before starting; install APKs and the arm64 execution bridge; view the screen and the logs.
- ModAVD is an Android emulator based on the AOSP Android Emulator plus a set of patches. It supports Windows and Apple Silicon macOS today, and more platforms are planned. This repository holds the programs that manage it: create, change and delete instances; start and shut down; the computer check before starting; install APKs and the arm64 execution bridge; view the screen and the logs.
- It manages one ModAVD root folder, that is, the folder the ModAVD release package unpacks to (it contains `mas-avd.json`, `sdk\` and `avd\`). The instance files and `mas-avd.json` are written the same way as in [AUTO-MAS](https://github.com/AUTO-MAS-Project/AUTO-MAS), and the tests compare against AUTO-MAS code byte for byte.
- The manager `ModAVD.exe` is for people; the CLI `modavd.exe` and its MCP server are for scripts, AUTO-MAS and AI assistants.

Expand Down Expand Up @@ -71,7 +71,7 @@ modavd [--root <dir>] [--json] [--quiet] [--verbose] <command> [args]
| `bridge <i> install\|uninstall\|verify` | Install, uninstall or check the arm64 execution bridge; it is installed automatically at start, so you normally do not run it by hand (see below) |
| `playstore <i> install\|uninstall\|status` | Add the Google Play Store to an instance, remove it, or check it (see below) |
| `gles32 <i> on\|off\|status` | Experimental: make an instance report GLES 3.2 (see below) |
| `disk <i> compact` | Compact a stopped instance's data disk, or skip rewriting when estimated savings are too small. Verify before atomically replacing the original, and report host usage before and after, including growth. Large disks have budgets of many hours and effectively do not time out in normal use; cancel to stop an operation. Requires NTFS/ReFS, no snapshots and room for the temporary image. See [budgets and result fields](internal/emu/COMPACT.md) |
| `disk <i> compact` | Compact a stopped instance's data disk, or skip rewriting when estimated savings are too small. Verify before atomically replacing the original, and report host usage before and after, including growth. Large disks have budgets of many hours and effectively do not time out in normal use; cancel to stop an operation. Supports NTFS/ReFS on Windows and APFS on Apple Silicon macOS; linked images and snapshots are rejected, and room for the temporary image is required. See [budgets and result fields](internal/emu/COMPACT.md) |
| `check [--memory M]` | Computer check before starting |
| `report-config [--no-clipboard]` | Copy the computer configuration and the game info from the running instances (read-only) |
| `collect-info [--out-dir D] [--stage-dir D] [--keep-stage] [--no-explorer]` | Collect a problem report and zip it (read-only). Ctrl+C before ZIP completion returns `canceled`, deletes the unfinished ZIP and removes staging; `--keep-stage` preserves staging and includes its path in the error |
Expand All @@ -84,6 +84,8 @@ modavd [--root <dir>] [--json] [--quiet] [--verbose] <command> [args]
- Root folder: `--root`; if not given, the environment variable `MODAVD_ROOT`; otherwise the folder containing `modavd.exe`, or its parent.
- From 0.3.0 there is no `restart`: `stop`, then `start`. An old call gets a usage error (exit code 2) that says so.

Apple Silicon macOS uses the SDK's native `qemu-img`. Host usage counts allocated filesystem blocks, excluding sparse holes. APFS clones can share extents, so a decrease in file allocation does not guarantee the same increase in volume free space. Ordinary log cleanup checks actual open files and preserves candidates that are active, changed, linked, or contain unexpected subdirectories. The diagnostics switch remains unavailable on macOS.

**The arm64 execution bridge**:

- It applies only to the games on the built-in list; other apps keep using the original translation layer. The bridge is installed in the instance's own system / vendor overlay and needs an emulator from 0.36 on.
Expand Down Expand Up @@ -274,17 +276,17 @@ Double-click `ModAVD.exe` in the package root: it starts a local server that lis

## Fetching the Google components

The ModAVD release package does not include adb (platform-tools 37.0.1) or the Android 14 Google APIs x86_64 system image (r14, about 1.5 GB, about 4.2 GB unpacked): they belong to Google, are governed by the Android Software Development Kit License Agreement, and cannot be redistributed. `modavd components fetch` downloads them from official channels and installs them into `sdk\`. The manager's "补全组件" button and this command share the same logic; the first interactive run asks for a download source and remembers it:
The ModAVD release package does not include adb (platform-tools 37.0.1) or a system image: Windows uses Android 14 Google APIs x86_64 (r14), while Apple Silicon macOS uses Android 15 Google APIs arm64-v8a (r9). They belong to Google, are governed by the Android Software Development Kit License Agreement, and cannot be redistributed. `modavd components fetch` downloads them from official channels and installs them into `sdk\`. The manager's "补全组件" button and this command share the same logic; the first interactive run asks for a download source and remembers it:

- First it fetches the full license text from `repository2-3.xml` on a mirror and displays it (stating which mirror it came from and which components will be downloaded), and continues only if you type `y`; otherwise nothing is downloaded and `downloads\` gets no extra files. `--accept-license` skips the prompt, but the full text is still fetched and displayed, and if it cannot be fetched it still exits; with `--json` it is required, otherwise the command always reports `usage` (exit code 2), before it even looks at the root folder and whether or not components are missing (up to 0.3.0 it succeeded when nothing was missing). The license text and the prompt are not affected by `--quiet`.
- Mirrors are tried in this order: googledownloads.cn → Tencent Cloud mirror → dl.google.com. When something is to be downloaded, a line "下载源:…" (download source) first says which ones this run uses and why (default / `--mirror` / `--mirror-url`). `--mirror` uses only one of them (case-insensitive); `--mirror-url` uses your own directory URL in place of those three (it can be given several times or comma-separated, and the URLs are tried in order). A mirror from which the license manifest could not be fetched is moved to the end when downloading.
- Component fetches and updates share the download implementation: data goes into `.part` files and interrupted transfers resume with `Range`. A 200 must match the expected size; a 200 answering a range request truncates the old data and resets progress to zero. A 206 must match the start, end and total size; a 416 keeps the existing partial file. Requests carry `Accept-Encoding: identity`, reject compressed responses, allow at most 10 redirects and use `ModAVDManager/<version>` as User-Agent. Components use `downloads\`; a complete local `.part` is verified first, and a bad one is downloaded again from the first mirror. Files are renamed only after size and SHA-1 verification. HTTP 4xx, a size mismatch, compressed content or a timeout switches to the next mirror immediately (the `.part` is kept so the next mirror can continue it); other errors are retried up to 3 times on the same mirror, waiting 3 seconds between tries.
- It unpacks to `sdk\.staging\`, and moves the result into place only after the whole package is unpacked and verified (key files, the SHA-256 pinned for the three adb files, the version); a missing `source.properties` is written in. A previously incomplete directory is renamed `<dir>.incomplete-<time>` and kept, with `-2`, `-3` and later suffixes on collisions. If a later component fails, the JSON error's `advice` also lists the moved directories. Delete them yourself once you are sure you do not need them. Ctrl+C stops it at any time and leaves no half-installed component.
- Components that are already complete are skipped; by default the zip is deleted after a successful install, and `--keep-downloads` keeps it.
- It refuses first if the path has non-ASCII characters, if the folder is not a ModAVD root folder, if `mas-avd.json` sets `sdkRoot`, or if there is not enough space (the download plus the unpacked size, plus 500 MB spare). `--test-free-space-mb` is for tests only and pretends that only that many MB are free.
- Timeouts are shared with `update`. `components fetch` accepts `--connect-timeout` (connecting, the TLS handshake and receiving the response headers; 1-600 seconds, default 20), `--stall-timeout` (not a single byte received; 1-600 seconds, default 30), `--manifest-timeout` (fetching the manifest as a whole; 1-1800 seconds, default 40). Proxy: if `HTTPS_PROXY` / `HTTP_PROXY` is set, it follows the environment variables; otherwise it uses a proxy set manually in the Windows "Internet Options". `NO_PROXY` applies to both; setting it alone does not disable the system proxy. Automatic configuration scripts (PAC) are not supported; in that case set `HTTPS_PROXY`.
- Timeouts are shared with `update`. `components fetch` accepts `--connect-timeout` (connecting, the TLS handshake and receiving the response headers; 1-600 seconds, default 20), `--stall-timeout` (not a single byte received; 1-600 seconds, default 30), `--manifest-timeout` (fetching the manifest as a whole; 1-1800 seconds, default 40). Proxy: if `HTTPS_PROXY` / `HTTP_PROXY` is set, it follows the environment variables; otherwise it uses a proxy set manually in Windows "Internet Options" or the current manual HTTP/HTTPS/SOCKS settings on Apple Silicon macOS. `NO_PROXY` applies to both; setting it alone does not disable the system proxy. Automatic configuration scripts (PAC) are not supported; in that case set `HTTPS_PROXY`.
- It writes only `downloads\`, `logs\fetch-components.log` (and the `.lock` beside it; only one fetch runs at a time per root folder), the two component directories under `sdk\` (with `--play-store` and `import-playstore` also `sdk\playstore`), and `sdk\.staging\`. It does not touch the adb server, does not write the registry, and does not need administrator rights. The log records only the start and end of each download; progress is shown but not logged.
- Only Windows has a component manifest; macOS and Linux return `unsupported` (exit code 4).
- Windows and Apple Silicon macOS have component manifests; Linux returns `unsupported` (exit code 4).
- Exit codes: not accepting the license agreement is 2 (`license_declined`); a path with Chinese characters or not enough space is 4 (`precheck_failed`), and a folder that is not a ModAVD root folder or has `sdkRoot` set is also 4 (`not_ready`); a fetch already in progress is 5 (`busy`); failing to download the license or the components from any mirror is 9 (`components_unavailable`), and a downloaded zip whose SHA-1 is wrong on every mirror, or that fails verification after unpacking, is also 9 (`components_rejected`); being unable to read the free space is 1.
- `components status` (the default) and the components entry of `check` give the same result, and the rule for judging is the same as in AUTO-MAS (the key files being present counts as installed). `fetch` is stricter about what counts as "complete" (following the script: the key files must be non-empty, and for adb the pinned hash and version number are also verified), so it can happen that `status` shows a component as installed while `fetch` still reinstalls it, in which case the old directory is renamed and kept.

Expand All @@ -311,7 +313,7 @@ go vet ./...
go test ./...
```

Tests run on Windows only. Optional environment variables:
The full test suite runs on Windows and Apple Silicon macOS in CI. Optional environment variables:

| Variable | Purpose |
| --- | --- |
Expand Down
Loading
Loading