Skip to content

Commit 43d91bc

Browse files
fix: package Android AAR compliance cross-platform
1 parent 68687e6 commit 43d91bc

6 files changed

Lines changed: 43 additions & 16 deletions

File tree

apps/android/lib/settings/settings_page.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class SettingsPage extends StatelessWidget {
7070
child: AboutListTile(
7171
icon: Icon(Icons.info_outline),
7272
applicationName: 'AikoBox',
73-
applicationVersion: '0.1.0-beta.2',
73+
applicationVersion: '0.1.0-beta.3',
7474
applicationLegalese: 'GPL-3.0',
7575
),
7676
),

apps/android/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: aikobox_android
22
description: AikoBox Android client.
33
publish_to: none
4-
version: 0.1.0-beta.2+2
4+
version: 0.1.0-beta.3+3
55

66
environment:
77
sdk: '>=3.12.2 <4.0.0'
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
# AikoBox v0.1.0-beta.2
1+
# AikoBox v0.1.0-beta.3
22

3-
AikoBox `v0.1.0-beta.2` 是首个同时提供 Windows x64 与 Android ARM64 的公开预发行版。本版重点修复 Windows 核心、系统代理、路由转换和备份恢复的高风险问题,并首次提供由固定发布密钥签名的 Android VPN 客户端。它仍是 Beta;升级或首次安装前,请保留可用的联网方案和配置备份。
3+
AikoBox `v0.1.0-beta.3` 是首个同时提供 Windows x64 与 Android ARM64 的公开预发行版。本版重点修复 Windows 核心、系统代理、路由转换和备份恢复的高风险问题,并首次提供由固定发布密钥签名的 Android VPN 客户端。它仍是 Beta;升级或首次安装前,请保留可用的联网方案和配置备份。
44

5-
AikoBox `v0.1.0-beta.2` is the first public prerelease for both Windows x64 and Android ARM64. It focuses on high-risk fixes in Windows core lifecycle, system proxy handling, route conversion, and backup recovery, and introduces an Android VPN client signed with a fixed release key. This is still a beta; keep a working connectivity fallback and configuration backup before installing or upgrading.
5+
AikoBox `v0.1.0-beta.3` is the first public prerelease for both Windows x64 and Android ARM64. It focuses on high-risk fixes in Windows core lifecycle, system proxy handling, route conversion, and backup recovery, and introduces an Android VPN client signed with a fixed release key. This is still a beta; keep a working connectivity fallback and configuration backup before installing or upgrading.
66

77
## 下载 / Downloads
88

9-
- `aikobox-windows-0.1.0-beta.2-x64-setup.exe`:Windows 10/11 x64 安装版;TUN 需要管理员授权。
10-
- `aikobox-windows-0.1.0-beta.2-x64-portable.exe`:Windows 10/11 x64 便携版;建议首次试用。
11-
- `aikobox-android-0.1.0-beta.2-arm64-v8a.apk`:仅适用于 ARM64-v8a、Android 7.0(API 24)或更高版本。
9+
- `aikobox-windows-0.1.0-beta.3-x64-setup.exe`:Windows 10/11 x64 安装版;TUN 需要管理员授权。
10+
- `aikobox-windows-0.1.0-beta.3-x64-portable.exe`:Windows 10/11 x64 便携版;建议首次试用。
11+
- `aikobox-android-0.1.0-beta.3-arm64-v8a.apk`:仅适用于 ARM64-v8a、Android 7.0(API 24)或更高版本。
1212
- 每个二进制文件均有同名 `.sha256`,并提供统一的 `SHA256SUMS.txt``RELEASE-MANIFEST.txt` 和第三方许可审计。
1313
- Release 同时附带 Android libbox、Windows sing-box 核心与 Windows sysproxy 的完整对应源码包、依赖许可证包、机器可读证据报告、独立 Notice 和组件校验和。统一 `SHA256SUMS.txt` 覆盖除其自身外的全部公开资产。
1414

15-
- `aikobox-windows-0.1.0-beta.2-x64-setup.exe`: installer for Windows 10/11 x64; TUN requires elevation.
16-
- `aikobox-windows-0.1.0-beta.2-x64-portable.exe`: portable Windows 10/11 x64 build; recommended for first-time testing.
17-
- `aikobox-android-0.1.0-beta.2-arm64-v8a.apk`: for ARM64-v8a devices running Android 7.0 (API 24) or newer only.
15+
- `aikobox-windows-0.1.0-beta.3-x64-setup.exe`: installer for Windows 10/11 x64; TUN requires elevation.
16+
- `aikobox-windows-0.1.0-beta.3-x64-portable.exe`: portable Windows 10/11 x64 build; recommended for first-time testing.
17+
- `aikobox-android-0.1.0-beta.3-arm64-v8a.apk`: for ARM64-v8a devices running Android 7.0 (API 24) or newer only.
1818
- Every binary has a matching `.sha256`; the release also includes `SHA256SUMS.txt`, `RELEASE-MANIFEST.txt`, and the third-party license audit.
1919
- The Release also carries complete corresponding source, dependency-license bundles, machine-readable evidence reports, standalone Notices, and component checksums for Android libbox, the Windows sing-box core, and Windows sysproxy. The unified `SHA256SUMS.txt` covers every public asset except itself.
2020

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aikobox",
3-
"version": "0.1.0-beta.2",
3+
"version": "0.1.0-beta.3",
44
"description": "Windows proxy client powered by sing-box with Clash YAML compatibility",
55
"private": true,
66
"license": "GPL-3.0-only",

scripts/license-android-libbox-release.mjs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
import { tmpdir } from 'node:os'
1616
import { basename, dirname, extname, join, relative, resolve } from 'node:path'
1717
import { fileURLToPath, pathToFileURL } from 'node:url'
18+
import AdmZip from 'adm-zip'
1819

1920
import {
2021
EXPECTED_GO_VERSION,
@@ -241,14 +242,21 @@ export function extractSource(sourceDir, destination) {
241242
return join(destination, `sing-box-${LIBBOX_VERSION}`)
242243
}
243244

244-
function extractLibbox(aarPath, temporaryRoot, goExe) {
245-
const entries = run('tar', ['-tf', aarPath]).replaceAll('\r\n', '\n').split('\n').filter(Boolean)
245+
export function readArm64LibboxFromAar(aarPath) {
246+
const archive = new AdmZip(aarPath)
247+
const entries = archive.getEntries().map((entry) => entry.entryName)
246248
const native = entries.filter((entry) => /^jni\/[^/]+\/[^/]+\.so$/.test(entry))
247249
if (native.length !== 1 || native[0] !== 'jni/arm64-v8a/libbox.so') {
248250
throw new Error(`AAR ABI gate failed: ${native.join(', ')}`)
249251
}
252+
const entry = archive.getEntry(native[0])
253+
if (!entry || entry.isDirectory) throw new Error('AAR libbox payload is missing')
254+
return entry.getData()
255+
}
256+
257+
function extractLibbox(aarPath, temporaryRoot, goExe) {
250258
const libboxPath = join(temporaryRoot, 'libbox.so')
251-
writeFileSync(libboxPath, run('tar', ['-xOf', aarPath, native[0]], { encoding: 'buffer' }))
259+
writeFileSync(libboxPath, readArm64LibboxFromAar(aarPath))
252260
const raw = run(goExe, ['version', '-m', libboxPath])
253261
const buildInfo = parseGoBuildInfo(raw)
254262
if (buildInfo.goVersion !== EXPECTED_GO_VERSION) {

scripts/license-android-libbox-release.test.mjs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'
33
import { tmpdir } from 'node:os'
44
import { join } from 'node:path'
55
import test from 'node:test'
6+
import AdmZip from 'adm-zip'
67

78
import {
89
auditCoverage,
910
isLegalFile,
1011
nativeInputsFromPackage,
1112
parseJsonStream,
1213
parseModuleInventory,
13-
parseVendorModules
14+
parseVendorModules,
15+
readArm64LibboxFromAar
1416
} from './license-android-libbox-release.mjs'
1517

1618
function inventory(count = 75) {
@@ -43,6 +45,23 @@ test('recognizes legal files without treating source files as notices', () => {
4345
assert.equal(isLegalFile('/module/license_test.go'), false)
4446
})
4547

48+
test('reads the ARM64 libbox payload from the ZIP-format AAR without invoking tar', () => {
49+
const fixture = mkdtempSync(join(tmpdir(), 'aikobox-aar-test-'))
50+
try {
51+
const aarPath = join(fixture, 'libbox.aar')
52+
const archive = new AdmZip()
53+
archive.addFile('jni/arm64-v8a/libbox.so', Buffer.from('arm64-libbox'))
54+
archive.writeZip(aarPath)
55+
assert.deepEqual(readArm64LibboxFromAar(aarPath), Buffer.from('arm64-libbox'))
56+
57+
archive.addFile('jni/x86_64/libbox.so', Buffer.from('unexpected-abi'))
58+
archive.writeZip(aarPath)
59+
assert.throws(() => readArm64LibboxFromAar(aarPath), /AAR ABI gate failed/)
60+
} finally {
61+
rmSync(fixture, { recursive: true, force: true })
62+
}
63+
})
64+
4665
test('detects linked native inputs and blocks incomplete coverage', () => {
4766
const fixture = mkdtempSync(join(tmpdir(), 'aikobox-license-test-'))
4867
try {

0 commit comments

Comments
 (0)