Add authenticated WiFi transport with BLE fallback

This commit is contained in:
2026-10-01 14:32:18 +08:00
parent 071f06d365
commit f011d8357d
55 changed files with 6327 additions and 29 deletions
@@ -1,5 +1,7 @@
# Android 环境、构建与交付
App 0.3.0 / versionCode 6 增加 BLE 会话内 WiFi 加速,协议 1.2;仅 debug。Android 使用固定 OkHttp 4.12.0,Gradle verification-metadata.xml 记录依赖 SHA-256。设备复用 FastAPI/uvicorn/cryptography,无新增板端依赖。保持设备 VERSION 和发布记录,不导出 OTA/IMG。
## 安装门槛
Android Studio 是正常安装软件,由用户运行已核验官方安装包。安装包放用户普通下载目录,不放仓库或 Codex bin。准备好后停止等待用户安装,不自动运行安装器。安装时建议采用默认位置,首次向导安装 Android SDK;不必创建项目,也不必先下载模拟器或 NDK。
@@ -48,7 +48,7 @@ def main():
build_date = re.search(r'BUILD_DATE = "([^"]+)"', build_config)[1]
manifest = dict(app_version=version, version_code=code, signing='debug', build_date=build_date,
status='development-validation-see-test-report', apk_sha256=digest(apk),
certificate_sha256=certificate, protocol_major=1, protocol_minor=1, minimum_android_api=26,
certificate_sha256=certificate, protocol_major=1, protocol_minor=2, minimum_android_api=26,
target_android_api=37, build_tools='36.0.0', toolchain=versions, sources=entries)
(destination / 'manifest.json').write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
(destination / 'SHA256SUMS').write_text(f'{digest(apk)} {name}\n', encoding='utf-8')
@@ -0,0 +1,7 @@
# 奇妙小屏幕 0.3.0 debug(versionCode 6)
仅 debug 签名,可覆盖安装相同调试证书的旧包。Android 8.0 以上,真实验证机为 Android 13。
本包为当前开发验证产物;验收范围和未验证项见 `../../../测试结果归档/实施状态.md`。不能将 APK 成功生成视为所有首版验收通过。设备需已部署移动控制功能,历史设备版本号本身不代表支持 BLE。
SHA-256:`0aa43b8d6cb64648aad4fb5bff6a9b5e3eb3b71b707a17bc67708d197b54e36d`。源码摘要与签名证书摘要见 manifest.json。
@@ -0,0 +1 @@
0aa43b8d6cb64648aad4fb5bff6a9b5e3eb3b71b707a17bc67708d197b54e36d 奇妙小屏幕-0.3.0-debug.apk
@@ -0,0 +1,203 @@
{
"app_version": "0.3.0",
"version_code": 6,
"signing": "debug",
"build_date": "2026-10-01 10:58 +08:00",
"status": "development-validation-see-test-report",
"apk_sha256": "0aa43b8d6cb64648aad4fb5bff6a9b5e3eb3b71b707a17bc67708d197b54e36d",
"certificate_sha256": "b413e68c0bd2311c491ebd087ac5791c7c2ad8267793f92f6055d5521bd3ef4d",
"protocol_major": 1,
"protocol_minor": 2,
"minimum_android_api": 26,
"target_android_api": 37,
"build_tools": "36.0.0",
"toolchain": {
"kotlin": "2.4.20",
"agp": "9.3.1",
"compose": "1.12.1",
"coroutines": "1.10.2",
"serialization": "1.9.0"
},
"sources": [
{
"path": "androidApp/build.gradle.kts",
"sha256": "5c456db18998f21af503350e626366ce951ebe6aea7d81a9595fd44a6fbe7ec0"
},
{
"path": "androidApp/src/androidTest/kotlin/org/qimiaoscreen/controller/AppLifecycleTest.kt",
"sha256": "7b75279ea8bba61fd9a35848339f765e931abb2748dcb2ab08f37f85afd21084"
},
{
"path": "androidApp/src/androidTest/kotlin/org/qimiaoscreen/controller/BleIntegrationTest.kt",
"sha256": "f286cf70cd00b7e872371f0fbc55f6be46e52602ef6890e974aca1c32eb006fa"
},
{
"path": "androidApp/src/androidTest/kotlin/org/qimiaoscreen/controller/LayoutTest.kt",
"sha256": "22a26ed18216edf21273b2fdd285865ce00c7d1e456eca61cb3e23064989bb42"
},
{
"path": "androidApp/src/androidTest/kotlin/org/qimiaoscreen/controller/LibraryBleCacheTest.kt",
"sha256": "01636b443b36532e8b6aa55eaf9ef0976697122362ca24f05a1da6bb958e419f"
},
{
"path": "androidApp/src/androidTest/kotlin/org/qimiaoscreen/controller/LibraryCacheTest.kt",
"sha256": "a225a1d2a59bee7f693acf82feefc285e4777a63c5c8a711b61523429e547360"
},
{
"path": "androidApp/src/androidTest/kotlin/org/qimiaoscreen/controller/WifiSwitchTest.kt",
"sha256": "5ce335ff84fee01230733971964fefde3fcc6103172d3c40fee64f50838b7bcf"
},
{
"path": "androidApp/src/androidTest/kotlin/org/qimiaoscreen/controller/WifiTransportTest.kt",
"sha256": "541d8b2368a7b8e835d4bc2fc07c974fe932c43d72ef488b50ad22dda3a4b03c"
},
{
"path": "androidApp/src/main/AndroidManifest.xml",
"sha256": "f46f93fb739fa984ee2ad247b0d40678c41b71454cd30be0b04ea780668f1a06"
},
{
"path": "androidApp/src/main/kotlin/org/qimiaoscreen/controller/AndroidBle.kt",
"sha256": "343fb5e0aff77a0bea81895eff9863f10907663210f42368f02c1ae840161340"
},
{
"path": "androidApp/src/main/kotlin/org/qimiaoscreen/controller/AndroidLibraryCache.kt",
"sha256": "c8904caa25123b0085678d8e01e6bbf27ab0eb25e3767334a539c1dc7aebdba1"
},
{
"path": "androidApp/src/main/kotlin/org/qimiaoscreen/controller/AndroidWifi.kt",
"sha256": "d94d52c524c1f23b50c283fde1157787f27f4b5e92362d5daea72ce4c435d839"
},
{
"path": "androidApp/src/main/kotlin/org/qimiaoscreen/controller/MainActivity.kt",
"sha256": "890ae503c6cc02b001f2d96a8c6240b10ad7e988b8e4d3374af85c83762422eb"
},
{
"path": "build.gradle.kts",
"sha256": "feb3b6e64b846f0408cc40e95ae4b632ce9288a56bd6151bc3bbcc46f0549b49"
},
{
"path": "gradle/libs.versions.toml",
"sha256": "ed393bb2b4d81a162f6b3d21968eeca113e23c2f5d5d22c3be9d104bc592a633"
},
{
"path": "gradle/verification-metadata.xml",
"sha256": "e44824772ec2c9913a7ac2ce3608478a6276524184b6ff9c0526d55f67cc91af"
},
{
"path": "gradle/wrapper/gradle-wrapper.jar",
"sha256": "497c8c2a7e5031f6aa847f88104aa80a93532ec32ee17bdb8d1d2f67a194a9c7"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"sha256": "2cb0f9ddf992a26fc4947c91019136bff5e1ccfbf93bd905402b1abf69d15bc5"
},
{
"path": "gradle.properties",
"sha256": "e7d684b7795fd04ab2e7e96038fa2bf4f9fd633578aa3bb2f5fe367b4f5ec159"
},
{
"path": "gradlew",
"sha256": "ab5c0cad16305af2e619c159c1f58dd68d07fab9c11e36701e109c0277407f7a"
},
{
"path": "gradlew.bat",
"sha256": "475c4f08cd57cf2faa819e7f36d72aa93f0ad646ea23a8f7fa3ef54dee1cbc52"
},
{
"path": "README.md",
"sha256": "7232ebbac0899152e312429fecaf6b3e14b31265b0c50a95c99a6213aa04b2cd"
},
{
"path": "settings.gradle.kts",
"sha256": "3a1adf811d65cfd2ce28bfeb711990511a29094b8a5b5378f2860c86c9fe83e2"
},
{
"path": "sharedCore/build.gradle.kts",
"sha256": "9a420e39e3c655f676572d4486e415dbc8b4fd45904db6ad7b64d7fcd71f084b"
},
{
"path": "sharedCore/src/commonMain/kotlin/org/qimiaoscreen/core/Controller.kt",
"sha256": "8c9fd985504340efc1fa82c2ad15f937bda51473d97f4fe5e63b8552ca0fa3e5"
},
{
"path": "sharedCore/src/commonMain/kotlin/org/qimiaoscreen/core/DeviceLink.kt",
"sha256": "35673e7e28d44c5a3d784a205d3f8f86ddcf534751b31b3e27e0ea93ec756747"
},
{
"path": "sharedCore/src/commonMain/kotlin/org/qimiaoscreen/core/LibraryCache.kt",
"sha256": "d260abe091fa35ad79a663cdae9284147a000e51d8ee1f87f6d7e28138de3fe6"
},
{
"path": "sharedCore/src/commonMain/kotlin/org/qimiaoscreen/core/Protocol.kt",
"sha256": "99264aff225076ef1b423801b9bba8797e0e06a9e759339bc52e896620e4b694"
},
{
"path": "sharedCore/src/commonMain/kotlin/org/qimiaoscreen/core/SecureChannel.kt",
"sha256": "bde40388bb74c9d47a4e099a14a0baeca3b6bda1539023dbd7dca831c6f24039"
},
{
"path": "sharedCore/src/commonMain/kotlin/org/qimiaoscreen/core/WifiTransport.kt",
"sha256": "3e0f4fe8ad47edb43ddd0acd720a0970afe902f5de937ce087a86eafc20143b2"
},
{
"path": "sharedCore/src/commonTest/kotlin/org/qimiaoscreen/core/ControllerRecoveryTest.kt",
"sha256": "98b05b59c42f714f0ff356a4ed942e1564ecf3c02ded9ed9a108fc7b1cba00e5"
},
{
"path": "sharedCore/src/commonTest/kotlin/org/qimiaoscreen/core/ProtocolTest.kt",
"sha256": "5d26d3a50c5887d72dc91b2081273fbe4a5a968f01451ef75ab78903d5d42217"
},
{
"path": "sharedCore/src/javaCryptoMain/kotlin/org/qimiaoscreen/core/JavaSecureChannel.kt",
"sha256": "f5dcc82c9dc7a4ab6851ade222eb333239b298637cdbf0dd08531838310bd0c9"
},
{
"path": "sharedCore/src/jvmTest/kotlin/org/qimiaoscreen/core/CryptoInteropTest.kt",
"sha256": "2ddb06c4476952a69bf01c0a3a7164625ae8c0bfe9194349450a2e254888d4b3"
},
{
"path": "sharedCore/src/jvmTest/kotlin/org/qimiaoscreen/core/HybridRpcTest.kt",
"sha256": "11956411e6323a60f1835dcf113958095d74e06947bdecb802076234dcab2435"
},
{
"path": "sharedCore/src/jvmTest/kotlin/org/qimiaoscreen/core/RpcTimeoutTest.kt",
"sha256": "fca298fb2266ee7e68e6df76d837f7f191e0046aa5ba321a304c4b4369e064a6"
},
{
"path": "sharedCore/src/jvmTest/kotlin/org/qimiaoscreen/core/WifiCryptoTest.kt",
"sha256": "ef051432f40fa9a5072efde6e590683a25f6eb2ca2ddb2fa1806089a8bfeeca0"
},
{
"path": "sharedCore/src/jvmTest/resources/protocol-v1.json",
"sha256": "6280953b95a3f5d1ae531d7feaa6a62848ffa3e438e58308d2a27f04723803dc"
},
{
"path": "sharedCore/src/jvmTest/resources/protocol-wifi-v1.json",
"sha256": "387fd59e65930001d190f4900b118958d41ee664c119ece9cd2ed15eed53d665"
},
{
"path": "sharedUi/build.gradle.kts",
"sha256": "d469b330d248647e6e93f98d69eb46730adab329ebaf71cbfd896d5426fd0ff1"
},
{
"path": "sharedUi/src/commonMain/kotlin/org/qimiaoscreen/ui/ControllerApp.kt",
"sha256": "46b8e61309fc60a194779695063bd4bf57dae9962481333dceb2062378d1acfc"
},
{
"path": "uiTest/build.gradle.kts",
"sha256": "958d9d5509c9b0fd3076f0d22a4544b66e11a4ba47e728107b8ea357cdaffaf3"
},
{
"path": "uiTest/src/main/AndroidManifest.xml",
"sha256": "ef50ab1e26f0caaadd7997799dd47d510cb7b4042b421ebe5354f4d2d42708dc"
},
{
"path": "uiTest/src/main/kotlin/org/qimiaoscreen/uitest/FixtureActivity.kt",
"sha256": "13d2cd43929d16216fc1e27d6965752e2699d1fa57f952093afe20530c155bde"
},
{
"path": "uiTest/src/main/kotlin/org/qimiaoscreen/uitest/IsolatedUiTest.kt",
"sha256": "1172df746c4ccc56923ba30c8de56eb0c042be8a7e1c6881d82ae6240d1914bd"
}
]
}