[Android][斐讯N1] 卡开机动画恢复:launcher 替换误删 directBootAware HOME
斐讯 N1 / p230(Amlogic S905D,Android 7.1.2,已 root,SuperSU)。用一个「替换桌面」的脚本把系统 launcher 换成爱家桌面后,设备一直卡在开机动画。adb 仍能连上(网络 adb),但永远进不了桌面。本文记录完整排查与恢复方法。
现象
- 一直停在开机动画,进不了系统。
adb 能连(状态 device),说明 adbd 起来了,问题在 framework / 开机后期,不是底层 kernel 挂掉。
关键判断命令:
adb shell getprop sys.boot_completed # 空 = 没启动完成
adb shell getprop init.svc.bootanim # running = 卡在开机动画
adb shell dumpsys user | grep -i "Started users state" # {0=0}=BOOTING {0=3}=UNLOCKED
adb shell "cmd package query-activities -a android.intent.action.MAIN -c android.intent.category.HOME"
adb logcat -d | grep -a "No home screen found" | tail -n1
确认特征:bootanim=running、user 状态 {0=0}、HOME 查询为空、日志反复 ActivityManager: No home screen found。
根本原因
替换脚本做了三件事,组合起来导致死锁:
- 安装 爱家桌面
com.aijia.launcher(为 Android 14 / targetSdk 34 打包,与 Android 7.1.2 不兼容)并 set-home-activity 设为持久 HOME。
pm disable 了 com.android.provision/.bluetooth.BluetoothActivity —— 它是本机唯一的 directBootAware、priority=1 的 SETUP_WIZARD HOME,在开机「锁定阶段」充当 HOME。
- 往
/system/app/AijiaLauncher 推了个坏包(split 解析失败的残留)。
机制:开机锁定阶段普通 launcher 不是 directBootAware,会被 PMS 过滤掉;provision 的兜底 HOME 又被禁用 → 锁定阶段没有任何可用 HOME → user 0 永远停在 STATE_BOOTING 无法解锁 → system_server 报 No home screen found → 卡开机动画。
易踩的坑:am start/query-activities 对这些桌面返回「does not exist / No activities found」,并不是组件被删,而是 user 锁定时 PMS 过滤了非 directBootAware 组件。直接重启会复现死锁,不能解决问题。
恢复步骤
1. 打破死锁(让本次开机先完成、解锁 user 0)
adb shell "am start -n com.android.tv.settings/.MainSettings"
adb shell "input keyevent 224" # 唤醒
adb shell "input keyevent 82" # 消掉 keyguard
adb shell dumpsys user | grep -i "Started users state" # 期望 {0=3}
adb shell getprop sys.boot_completed # 期望 1
到 {0=3} 后,普通 launcher 组件才可解析。
2. 拿 root(SuperSU,人工授权)
SuperSU 默认对 shell 静默拒绝。让用户盯着投屏点 授予/Grant(选「记住」),重试到 uid=0:
adb shell 'su -c "id" 2>&1; echo RC=$?' # 期望 uid=0(root)
若秒拒不弹窗,打开 SuperSU 让用户把「默认访问」设为提示/允许,或给 (shell) 授权:
adb shell "monkey -p eu.chainfire.supersu -c android.intent.category.LAUNCHER 1"
adb exec-out screencap -p > /tmp/supersu.png # 截图引导点按
3–4. SELinux 临时 permissive + 重新启用兜底 HOME
root 的 su 上下文是 u:r:toolbox:s0,enforcing 时连不上 package 服务(Can't find service: package),需临时放开:
adb shell 'su -c "setenforce 0"'
adb shell 'su -c "pm enable com.android.provision/com.android.provision.bluetooth.BluetoothActivity"'
该组件 directBootAware=true、priority=1,是保证以后每次都能正常过锁定阶段的关键。设备已激活(settings get global device_provisioned == 1),向导会直接放行。
5. 设定目标桌面为 HOME
# 启蒙桌面 asyt2
adb shell "cmd package set-home-activity com.asyt2.linearlauncher/.MainActivity"
# 或 原厂 Phicomm 桌面
# adb shell "cmd package set-home-activity com.phicomm.launcherush.debug/com.phicomm.launcherush.activities.ApplicationList"
adb shell "input keyevent 3" # HOME
adb shell "dumpsys window windows" | grep -i mCurrentFocus
cmd package resolve-activity -c HOME 仍会显示 provision(优先级高),这是正常的——AMS 实际启动 HOME 时会遵循 set-home-activity 设的首选。
6. 卸载爱家桌面 + 清理 /system 残留
adb uninstall com.aijia.launcher
adb shell 'su -c "mount -o rw,remount /system"'
adb shell 'su -c "rm -rf /system/app/AijiaLauncher"'
adb shell 'su -c "mount -o ro,remount /system"'
7. 恢复 SELinux、重启、验证无人值守开机
adb shell 'su -c "setenforce 1"'
adb reboot
# 网络 adb 重连:sleep 60; adb connect <ip>:5555
adb shell getprop sys.boot_completed # 1
adb shell getprop init.svc.bootanim # stopped
adb shell dumpsys user | grep -i "Started users state" # {0=3}
adb shell "dumpsys window windows" | grep -i mCurrentFocus # 目标桌面
成功标志:自动开机直达目标桌面,无需手动消 keyguard。
关键坑位小结
- 别只重启:纯重启会复现死锁;持久修复在于第 4 步重新启用 provision 的 directBootAware 兜底 HOME。
su 上下文 u:r:toolbox:s0 enforcing 时调不了 pm/cmd package → 先 setenforce 0,做完 setenforce 1。
- 改系统组件
pm enable / set-home-activity 必须走 su(shell 会 SecurityException);shell 只能做 adb uninstall 和查询。
- 取
/system 里的 APK 用 adb exec-out cat <path> > out.apk(adb pull 可能报 does not exist)。
- 查 APK 真实入口:
aapt dump badging($ANDROID_HOME/build-tools/*/aapt)。
- 「
am start does not exist / HOME 查询为空」往往是 user 锁定期的 PMS 过滤,不代表组件丢失。
[Android][斐讯N1] 卡开机动画恢复:launcher 替换误删 directBootAware HOME
现象
adb能连(状态device),说明 adbd 起来了,问题在 framework / 开机后期,不是底层 kernel 挂掉。关键判断命令:
确认特征:
bootanim=running、user 状态{0=0}、HOME 查询为空、日志反复ActivityManager: No home screen found。根本原因
替换脚本做了三件事,组合起来导致死锁:
com.aijia.launcher(为 Android 14 / targetSdk 34 打包,与 Android 7.1.2 不兼容)并set-home-activity设为持久 HOME。pm disable了com.android.provision/.bluetooth.BluetoothActivity—— 它是本机唯一的directBootAware、priority=1 的 SETUP_WIZARD HOME,在开机「锁定阶段」充当 HOME。/system/app/AijiaLauncher推了个坏包(split 解析失败的残留)。机制:开机锁定阶段普通 launcher 不是
directBootAware,会被 PMS 过滤掉;provision 的兜底 HOME 又被禁用 → 锁定阶段没有任何可用 HOME → user 0 永远停在STATE_BOOTING无法解锁 →system_server报No home screen found→ 卡开机动画。恢复步骤
1. 打破死锁(让本次开机先完成、解锁 user 0)
到
{0=3}后,普通 launcher 组件才可解析。2. 拿 root(SuperSU,人工授权)
SuperSU 默认对 shell 静默拒绝。让用户盯着投屏点 授予/Grant(选「记住」),重试到
uid=0:若秒拒不弹窗,打开 SuperSU 让用户把「默认访问」设为提示/允许,或给
(shell)授权:3–4. SELinux 临时 permissive + 重新启用兜底 HOME
root 的 su 上下文是
u:r:toolbox:s0,enforcing 时连不上package服务(Can't find service: package),需临时放开:该组件
directBootAware=true、priority=1,是保证以后每次都能正常过锁定阶段的关键。设备已激活(settings get global device_provisioned== 1),向导会直接放行。5. 设定目标桌面为 HOME
6. 卸载爱家桌面 + 清理 /system 残留
7. 恢复 SELinux、重启、验证无人值守开机
成功标志:自动开机直达目标桌面,无需手动消 keyguard。
关键坑位小结
su上下文u:r:toolbox:s0enforcing 时调不了pm/cmd package→ 先setenforce 0,做完setenforce 1。pm enable/set-home-activity必须走su(shell 会SecurityException);shell 只能做adb uninstall和查询。/system里的 APK 用adb exec-out cat <path> > out.apk(adb pull可能报 does not exist)。aapt dump badging($ANDROID_HOME/build-tools/*/aapt)。am startdoes not exist / HOME 查询为空」往往是 user 锁定期的 PMS 过滤,不代表组件丢失。