Skip to content
Merged
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
Binary file modified cmd/modavd-gui/rsrc_windows_amd64.syso
Binary file not shown.
2 changes: 1 addition & 1 deletion internal/buildinfo/buildinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package buildinfo
// Version of modavd itself, kept in the source rather than set with -ldflags -X: release builds must come out byte
// for byte the same for the same source (Mirror 酱 ships per-file deltas, and a version stamped per package would
// change the exe in every release). The ModAVD package version comes from the root at run time.
var Version = "0.11.0"
var Version = "0.12.0"

// Protocol is the version of the machine-readable contract: the commands, the JSON written by `--json`, the exit codes
// and the MCP tool schemas. Callers such as AUTO-MAS check it (`modavd version --json`) before relying on a field.
Expand Down
8 changes: 5 additions & 3 deletions internal/emu/clocksource.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ import (

const (
// clocksourceScript prints the current clock source, the available ones and the guest's machine, separated by
// "---" lines: one fixed command line without variables, readable without root.
clocksourceScript = "cat /sys/devices/system/clocksource/clocksource0/current_clocksource; echo ---; " +
"cat /sys/devices/system/clocksource/clocksource0/available_clocksource; echo ---; uname -m"
// "---" lines: one fixed command line without variables. As root: on the Android 14 images SELinux does not let
// the adb shell user read this sysfs directory (every boot logged "Permission denied").
clocksourceScript = "su 0 sh -c 'cat /sys/devices/system/clocksource/clocksource0/current_clocksource; echo ---; " +
"cat /sys/devices/system/clocksource/clocksource0/available_clocksource; echo ---; uname -m'"
clocksourceTimeout = 10 * time.Second
// clocksourceKernelCommand is the guest kernel log as root (logcat -b kernel needs it on these images; dmesg may
// have been overwritten by then). Filtered here, on the host, so no pipe runs in the guest.
Expand Down Expand Up @@ -134,6 +135,7 @@ func (m *Manager) checkClocksource(i int, cfg *avd.Ini, run func(command string,
rec.Available, rec.Arch, rec.X86 = available, arch, x86Guest(arch, cfg)
switch {
case !ok:
rec.Available = "" // whatever stood there is part of an error text
rec.Error = orText(tail(strings.Join(strings.Fields(res.Out), " "), 200), fmt.Sprintf("退出码 %d", res.Code))
m.Log.Warnf("实例 %d 读不到客体时钟源(%s),这次开机不判断", i, rec.Error)
case !rec.X86 || current == "tsc":
Expand Down
17 changes: 17 additions & 0 deletions internal/emu/clocksource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,20 @@ func TestCheckClocksourceRecordUnwritable(t *testing.T) {
t.Errorf("log = %s", fmt.Sprint(*lines))
}
}

// The clock source is read as root: the adb shell user is denied this sysfs directory on the Android 14 images
// (ModAVD/ModAVD#110; every boot of the 0.41.0 candidate logged "Permission denied").
func TestClocksourceScriptRunsAsRoot(t *testing.T) {
if !strings.HasPrefix(clocksourceScript, "su 0 sh -c '") || !strings.HasSuffix(clocksourceScript, "'") ||
strings.Count(clocksourceScript, "'") != 2 {
t.Fatalf("clocksourceScript must be one su 0 sh -c '…' command: %q", clocksourceScript)
}
}

func TestParseClocksourceDenied(t *testing.T) {
out := "cat: /sys/devices/system/clocksource/clocksource0/current_clocksource: Permission denied\n---\n" +
"cat: /sys/devices/system/clocksource/clocksource0/available_clocksource: Permission denied\n---\nx86_64\n"
if current, _, arch, ok := parseClocksource(out); ok || current != "" || arch != "x86_64" {
t.Fatalf("denied read parsed as current=%q arch=%q ok=%v", current, arch, ok)
}
}
3 changes: 3 additions & 0 deletions release/0.12.0.SHA256SUMS.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
320d5d6a6695a3f3264b32320e1789c7f6f89500581854d05bfea7838fb7168b ModAVD.exe
d8d34bd920c733d20064cfcbfe90c77d694f63f3dcbf2be1022c8e223edb9fb9 ModAVDManager-0.12.0-win-x64.zip
fbfbd8bb52e3215b732e1e97757de6a1868f145d13ba7ff151095d241a3e28b5 tools/modavd.exe
62 changes: 62 additions & 0 deletions release/0.12.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# ModAVDManager v0.12.0

- `ModAVD.exe`:`320d5d6a6695a3f3264b32320e1789c7f6f89500581854d05bfea7838fb7168b`
- `tools/modavd.exe`:`fbfbd8bb52e3215b732e1e97757de6a1868f145d13ba7ff151095d241a3e28b5`

随 ModAVD 0.41.0 进包。下面是相对 v0.11.0 的改动。这一版主要是:开机前发现截图共享内存还被别的程序拿着时,写出是哪个程序;新建时语言没设成不再算新建失败;开机后记下客体的时钟源,给排查变慢的问题取证。

## 新增

- 开机前,如果这台实例的截图共享内存还在(上次那台模拟器退出后,有程序一直拿着它,多半是 MAA 这类用截图的工具),记一条警告,写出拿着它的程序和 pid,开机照常进行。这时截图共享可能开不起来,用它截图的工具会变慢;把这些程序退出后再开机就好。问题包里也单独记一节:没在运行的实例还留着截图共享内存的,写出拿着它的程序;没有就不出这一节。(ModAVDManager#168,ModAVD/ModAVD#210)
- 每次开机后设置的最后一步,记下客体的时钟源,写进这次开机的日志。x86_64 客体的时钟源不是 tsc 时(这次开机期间整体会变慢,关机再开才恢复),记一条警告,马上存下客体的内核日志到 `logs\mas_<i>-<时间>-clocksource.txt`,每台实例留最新 5 份。读不到时只记一句,不拦开机。问题包里实例那一节多一行最近一次开机的时钟源,并带上最新 3 份这类内核日志。这一条只是取证,不改时钟源本身。(ModAVDManager#171,ModAVD/ModAVD#110)

## 变更

- 模拟器的构建号(`sdk\emulator\source.properties` 的 `Pkg.BuildId`、包清单 `modavd-manifest.json` 的 `build`)除了 `mas-N`,也认版本号的写法(比如 `0.42.0`),开机检查、装包和更新都一样。这是为以后的模拟器改用版本号当构建号做准备;ModAVD 0.41.0 的模拟器仍是 `mas-41`。(ModAVDManager#169)

## 修复

- 新建实例时语言没设成,不再让这次新建算失败:新建照常完成并正常关机,语言留到下次冷启动再设。(ModAVDManager#167,ModAVD/ModAVD#206)
- 打开运行中实例的设置页时,读安卓里的语言和时区只读系统属性,不再往客体里推送程序、用 root 起进程。(ModAVDManager#167,ModAVD/ModAVD#206)

## 给调用方(AUTO-MAS)

- `protocol` 还是 2:没有删命令、参数和 `--json` 字段,没有新的错误码和退出码。调用方不用改。
- `--json`:根信息多一个字符串 `build_id`(模拟器的 `Pkg.BuildId` 原样,比如 `mas-41`;不知道时省略)。整数 `build` 保留,构建号是 `mas-N` 时还是 N,以后是版本号写法时为 0。`update status` 的 `current_build` 以后也可能是版本号写法。(ModAVDManager#169)
- 新建时语言没设成,`create` 不再报失败,也不用 `create --resume N`;`regional <i>` 里照旧看得到 `pending_language`。(ModAVDManager#167)

## 下载与核对

用 Go 1.26.5、`GOTOOLCHAIN=local` 运行仓库里的 `build.ps1`,能编出相同的字节。单独下载的包里还有 Go 的许可原文和文件清单。请用附件 `SHA256SUMS.txt` 核对 zip 和解压出的两个 exe,例如在 PowerShell 里运行 `Get-FileHash .\ModAVDManager-0.12.0-win-x64.zip -Algorithm SHA256`。

单独下载的管理器不会自己更新,新版本要手动替换;ModAVD 包里的那份随 ModAVD 整包一起更新。单独使用时请给 `--root` 或设置 `MODAVD_ROOT`,否则会提示找不到 ModAVD 根目录。不要把单独下载的 zip 解压到 ModAVD 根目录,覆盖整包里的文件。

## English

Shipped in ModAVD 0.41.0. Changes since v0.11.0. This release mostly brings: before a boot, a screenshot shared-memory region still held by another program is reported with that program's name; a language that could not be set at creation no longer fails the creation; each boot records the guest's clock source, as evidence for slowdowns.

### New

- Before a boot, when the instance's screenshot shared-memory region still exists (a program kept holding it after the last emulator exited, most likely a screenshot tool such as MAA), a warning names the programs holding it and their pids; the boot goes on. Frame sharing may then not start, and tools that take screenshots through it get slower; quit those programs and boot again. The problem report has a section of its own for regions left by instances that are not running, with the programs holding them; without any, the section is not there. (ModAVDManager#168, ModAVD/ModAVD#210)
- As the last step of the setup after each boot, the guest's clock source is written to that boot's log. When an x86_64 guest's clock source is not tsc (everything is slower until the instance is shut down and started again), a warning is logged and the guest's kernel log is saved right away to `logs\mas_<i>-<time>-clocksource.txt`, keeping the latest 5 per instance. When it cannot be read, one line is logged and the boot is not blocked. The problem report adds a line with the latest boot's clock source to each instance's section, and takes the latest 3 of these kernel logs. This only collects evidence; it does not change the clock source. (ModAVDManager#171, ModAVD/ModAVD#110)

### Changes

- The emulator's build ID (`Pkg.BuildId` in `sdk\emulator\source.properties`, `build` in the package list `modavd-manifest.json`) may be a version (for example `0.42.0`) as well as `mas-N`, for the start check, package installs and updates alike. This prepares for later emulators that use the version as their build ID; the emulator in ModAVD 0.41.0 is still `mas-41`. (ModAVDManager#169)

### Fixes

- When the language could not be set at creation, the creation no longer counts as failed: it finishes and shuts down normally, and the language is set at the next cold start. (ModAVDManager#167, ModAVD/ModAVD#206)
- Opening the settings of a running instance reads Android's language and time zone from system properties only, without pushing a program into the guest or starting one as root. (ModAVDManager#167, ModAVD/ModAVD#206)

### For callers (AUTO-MAS)

- `protocol` is still 2: no command, option or `--json` field was removed, and there are no new error codes or exit codes. Callers need no change.
- `--json`: the root information adds a string `build_id` (the emulator's `Pkg.BuildId` as is, for example `mas-41`; omitted when unknown). The integer `build` stays: N for a `mas-N` build, 0 for a later build ID written as a version. `current_build` of `update status` may also be a version later. (ModAVDManager#169)
- When the language could not be set at creation, `create` no longer fails and needs no `create --resume N`; `regional <i>` still shows `pending_language`. (ModAVDManager#167)

### Download and verification

Running the repository's `build.ps1` with Go 1.26.5 and `GOTOOLCHAIN=local` builds the same bytes. The standalone package also carries Go's license text and the file list. Check the zip and the two extracted exe files with the attached `SHA256SUMS.txt`, for example `Get-FileHash .\ModAVDManager-0.12.0-win-x64.zip -Algorithm SHA256` in PowerShell.

The standalone manager does not update itself; replace it by hand for a new version. The copy in the ModAVD package is updated with the whole ModAVD package. When using it standalone, pass `--root` or set `MODAVD_ROOT`, or it reports that it cannot find the ModAVD root. Do not extract the standalone zip into a ModAVD root over the package's files.
Binary file modified rsrc_windows_amd64.syso
Binary file not shown.
Loading