[Device] 鸿蒙/EMUI 上 app_prepare 返回 "APS refused native resolution (status=-3)" 时任务直接终止(表现为虚拟屏黑屏),建议降级为告警
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 72/100
Research direction
Read assets/overlays/android_app_launch.py, especially app_start() and its app_prepare handling. Reproduce the reported status=-3 response on the described HarmonyOS device, then trace how launch proceeds when native resolution preparation is refused. Done means this refusal no longer immediately terminates the task, while the existing restart-loop protection is preserved.
Written by the indexing model from the issue text.
Description
环境
| 项目 | 环境 |
|---|---|
| 设备 | HUAWEI DBY-W09(MatePad 11),HarmonyOS 4.2.0.213(C00E100),ro.build.version.release=12,API 31,arm64-v8a |
| Root | Magisk 27.0(后端选的是 ROOT) |
| AzurPilot for Android | 1.3.96、1.3.131 均可复现 |
| 游戏 | com.bilibili.azurlane |
现象
点「开始运行」后任务立刻失败,应用「虚拟屏」页一直是黑屏,看起来像“模拟器跑不起来”。
session.log里只有:CRITICAL [错误] 任务需要人工介入(将尝试自动恢复) 原因:当前状态无法由自动化流程安全判断或修复。以及更早一次的
设备初始化需要人工介入,都没有真正的异常信息。真正的错误只出现在
files/debug/root_launch_debug.log和直接调桥的返回里:java.lang.IllegalStateException: APS refused native resolution for com.bilibili.azurlane (status=-3)
复现步骤(概率 100%)
adb forward tcp:22301 tcp:22301 # 桥在本机 127.0.0.1:22301 # 1) 能力探测 {"method":"ping","id":1} # → {"ok":true,"capabilities":{"nativeGameResolution":true,"appFocus":true,...},"displayId":3,...}2) 准备原生分辨率(游戏在前台/后台、是否已获得焦点都一样)
{"method":"app_prepare","package":"com.bilibili.azurlane","displayId":3,"id":2}
→ {"ok":false,"error":"APS refused native resolution for com.bilibili.azurlane (status=-3)","id":2}
根因
assets/overlays/android_app_launch.py 里,app_start() 把 app_prepare 当成了致命步骤:
ping = self._azurpilot_android_call({'method': 'ping'})
if ping.get('capabilities', {}).get('nativeGameResolution'):
try:
response = self._azurpilot_android_call({
'method': 'app_prepare', 'package': target, 'displayId': ping['displayId'],
})
if not response.get('ok'):
raise RuntimeError(response.get('error', 'unknown'))
except Exception as error:
# 启动失败不能继续走 Restart,否则同一裁切画面会形成无限重启循环。
raise module.RequestHumanTakeover(
f'无法关闭游戏分辨率缩放,请检查系统权限:{error}') from error
但 app_prepare 的作用只是“关闭兼容缩放”。在鸿蒙上这一步被系统拒绝(status=-3,APS 应该是华为那边的分辨率/缩放服务),
跳过它之后游戏依然能在虚拟屏上以 1280×720 正常渲染,模板匹配、OCR、点击全部正常。
验证:把 app_prepare 的失败降级为告警后,同一台设备同一版本完全跑通
在 _azurpilot_android_call() 里拦截 app_prepare 的失败响应,返回 {'ok': True, 'skipped': True, ...} 并打一条 warning,
其余逻辑不动,日志立刻变成:
00:38:22 应用启动: com.bilibili.azurlane
00:38:22 WARNING AzurPilotAndroid: 跳过原生分辨率准备(APS refused native resolution for com.bilibili.azurlane (status=-3))
00:38:24 [重启] 等待 30.0 秒让应用启动和稳定...
00:38:57 [重启] 应用启动成功并正在运行
00:40:14 [委托] 日常资源开发III
00:40:18 [委托-完成] 委托完成时间: ['2026-10-26 11:00:18', ...]
00:40:18 调度器: 开始任务 Research
虚拟屏截图(screencap -d <vid>)1280×720,战斗画面、演习计数 OCR 均正常。
补充:黑屏的另一半原因(说明 app_focus 是必要的)
游戏通过 am start --display N 拉到虚拟屏后,该显示上 mCurrentFocus=null / mFocusedApp=null,
SurfaceFlinger 里 SurfaceView... 层 isVisible=false、buffer=0x0,screencap -d N 全黑。
对虚拟屏注入一次触摸后:
mCurrentFocus=Window{... com.bilibili.azurlane/com.manjuu.azurlane.MainActivity}
SurfaceView... isVisible=true buffer=slot=62 ...
画面立刻出来。也就是说 app_focus 这一步是对的、必须的,只是它排在 app_prepare 之后,被异常挡掉了。
建议
app_prepare失败(尤其是APS refused ... status=-3这种“系统不支持”类错误)时降级为logger.warning并继续,
和app_focus的处理方式保持一致;如果担心裁切问题,可以只在status=-3/refused时降级。- 或者调整顺序:先
app_focus再app_prepare,或无论 prepare 成功与否都执行 focus。 alas.py里device属性捕获RequestHumanTakeover时调用的是logger.error_context(..., 不带 exc),
建议把异常原文带上(exc=e),否则用户只能看到“设备连接或设备参数校验未通过”,无法定位。
临时规避(其他用户可参考)
更新后将 module/device/method/azurpilot_android.py 末尾追加:
def _azp_huawei_call(self, payload, frame=None):
response = _azp_huawei_original(self, payload, frame)
if not response.get('ok') and payload.get('method') == 'app_prepare':
logger.warning('AzurPilotAndroid: 跳过原生分辨率准备(%s)' % response.get('error'))
return {'ok': True, 'skipped': True, 'reason': response.get('error')}
return response
_azp_huawei_original = AzurPilotAndroid._azurpilot_android_call
AzurPilotAndroid._azurpilot_android_call = _azp_huawei_call
注意:应用更新会重新解压运行时,这个补丁需要重打。
- Dominant language
- Kotlin
- Stars
- 41
- Forks
- 2
- Avg merge
- 12h 33m
- Merged PRs (30d)
- 3
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from wess09/AzurPilot-for-Android
-
紧急委托[T4]战败后,异常进入活动T5Open
Difficulty 3/5 1-2 days Newbie friendliness 48/100
-
Difficulty 3/5 1-2 days Newbie friendliness 35/100
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
wess09/AzurPilot-for-Android#27 · 1 comment ·
-
无法正常打主线图,会卡在如下界面Open
Difficulty 4/5 3-5 days Newbie friendliness 22/100
-
机型支持列表Opendocumentation
Difficulty 1/5 Under an hour Newbie friendliness 20/100
wess09/AzurPilot-for-Android#1 · 44 comments ·
All issues in wess09/AzurPilot-for-Android
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
unconfirmed
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
thunderbird/thunderbird-android#11893 · 1 comment ·
Maintainers usually reply within 2 days
-
Difficulty 1/5 Under an hour Newbie friendliness 65/100
Droid-Deck/DroidDeck#2198 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
world-federation-of-advertisers/cross-media-measurement#4846 ·
Maintainers usually reply within 1 day