车载应用管理定制:PackageManagerService定制、应用安装策略、预装应用管理、应用权限与沙箱

各位好,今天我们聊一个车载系统里绕不开的话题——应用管理。说实话,车载上的应用管理和手机端差别挺大的。手机你装个App,最多就是占点存储、耗点电。但在车上,一个不靠谱的应用可能导致导航卡顿、仪表盘黑屏,甚至影响行车安全。所以,车载系统对应用的管理必须更严格、更精细。

我最早接触车载项目时,客户提的第一个需求就是:“能不能让第三方应用装不上来?” 当然,这是极端情况。更常见的需求是:预装哪些应用、怎么装、装完后权限怎么管、多用户场景下怎么隔离。这些,都绕不开一个核心服务——PackageManagerService(简称PMS)。

核心观点:车载应用管理的本质,是在Android原生PMS基础上,叠加车规级的安全策略、安装策略和权限管控策略。

PackageManagerService定制:从“能用”到“可控”

PMS是Android系统里管理应用包的核心服务。安装、卸载、查询、权限分配,全归它管。在车载场景下,我们通常需要对PMS做以下几类定制:

  • 安装来源管控:只允许特定来源(如系统预装、OEM商店、adb调试)安装应用,禁止用户随意安装APK。
  • 安装路径重定向:车载存储分区通常有严格规划,系统应用、预装应用、用户应用要分开放。
  • 安装策略注入:比如安装前检查签名、检查目标SDK版本、检查是否与车辆功能冲突。
  • 多用户隔离:驾驶位、副驾驶、后排娱乐屏,可能对应不同用户,PMS需要支持按用户管理应用。

我曾在某个项目中,客户要求“只有经过我们签名的应用才能安装”。实现方式其实不复杂——在PMS的installPackage流程中插入一个签名校验钩子。嗯,这里要注意,不能直接改PMS的源码,那样升级维护太痛苦。我建议用策略注入的方式,通过系统属性或配置文件来控制校验逻辑。

// 伪代码:在PMS安装流程中插入签名校验
public class CarPackageManagerService extends PackageManagerService {
    @Override
    public void installPackage(InstallArgs args) {
        // 检查安装来源
        if (!isInstallSourceAllowed(args.installSource)) {
            throw new SecurityException("安装来源不被允许");
        }
        // 检查签名
        if (!verifySignature(args.packageName, args.signatures)) {
            throw new SecurityException("签名校验失败");
        }
        super.installPackage(args);
    }

    private boolean isInstallSourceAllowed(int source) {
        // 从系统属性读取允许的来源列表
        String allowedSources = SystemProperties.get("persist.car.install.sources", "0,2");
        return Arrays.asList(allowedSources.split(",")).contains(String.valueOf(source));
    }
}

个人经验:我曾经在定制PMS时,直接修改了PackageManagerService.java的源码。结果每次Google推送安全补丁,都要手动合并代码,痛苦不堪。后来改用SystemProperties + 策略模式,维护成本直线下降。

应用安装策略:不是所有App都能上车

车载应用的安装策略,说白了就是“什么能装、什么不能装、怎么装”。我把它拆成三个维度:

维度 策略 说明
安装来源 白名单制 只允许系统应用、OEM商店、特定adb来源安装
安装时机 延迟安装 / 静默安装 车辆启动后、停车时、或特定条件下触发安装
安装校验 签名 + 权限 + 兼容性 校验签名是否匹配、权限是否越界、SDK版本是否兼容

你想想看,如果用户在行驶中安装一个大型游戏,CPU和IO都被占满,导航卡顿怎么办?所以,我一般建议在车辆P档(驻车)时才能安装应用。这个逻辑可以在CarPackageManagerService中监听车辆状态来实现。

// 伪代码:驻车时才能安装
public class CarInstallStrategy {
    private Car car;
    private boolean isParked;

    public boolean canInstall() {
        // 获取车辆状态
        int gear = car.getGear();
        isParked = (gear == Car.GEAR_PARK);
        return isParked;
    }
}

避坑指南:我曾经遇到一个坑——静默安装时没有做并发控制。结果同时有3个应用在安装,导致系统IO飙升,中控屏卡了十几秒。后来加了一个安装队列,每次只允许一个应用安装,问题解决。

预装应用管理:出厂就定好的“规矩”

预装应用是车载系统的“基本盘”。导航、音乐、语音助手、车辆设置……这些应用必须在出厂前就装好,而且不能随便卸载。预装应用的管理,主要涉及以下几个方面:

  • 预装分区:通常放在/system/priv-app/product/app分区,只读挂载,防止被篡改。
  • 预装列表:通过Android.mkAndroid.bp文件配置,编译时打包进系统镜像。
  • 预装更新:预装应用可以通过OEM商店更新,但更新包安装到/data/app分区,回滚时恢复出厂版本。
  • 预装卸载保护:普通用户无法卸载预装应用,但可以禁用(disable)。

我记得有个项目,客户要求预装应用在出厂后不能删除,但用户可以通过“恢复出厂设置”来清除数据。这个实现其实很简单——把预装应用放在/system分区,用户数据放在/data分区。恢复出厂设置时,只清/data/system不动。

关键点:预装应用的签名必须统一管理。我建议所有预装应用使用同一个平台签名,这样它们之间可以共享UID,方便权限管理。

应用权限与沙箱:安全是底线

车载应用的权限管理,比手机严格得多。手机上的“位置权限”可能只是用来推荐餐厅,但车上的位置权限可能涉及车辆定位、轨迹记录。一旦泄露,后果严重。

Android原生的权限模型是基于用户授予的,但车载场景下,很多权限应该是系统预授权强制拒绝的。比如:

  • 车辆控制权限:如车窗、空调、门锁——只有系统应用或特定签名应用才能获取。
  • 车辆数据权限:如车速、里程、电池状态——需要用户明确授权,且只能用于特定场景。
  • 通信权限:如蓝牙、WiFi、蜂窝网络——需要限制后台扫描,防止耗电。

我一般会在PermissionManagerService中增加一个车载权限策略层。比如,定义一个car_permissions.xml文件,列出哪些应用可以获取哪些敏感权限。安装时,PMS会读取这个文件,自动授予或拒绝权限。

<!-- car_permissions.xml 示例 -->
<car-permissions>
    <!-- 系统应用自动获取车辆控制权限 -->
    <allow package="com.example.carcontrol" permission="android.car.permission.CAR_CONTROL" />
    <!-- 第三方应用需要用户确认 -->
    <prompt package="com.example.navi" permission="android.car.permission.CAR_LOCATION" />
    <!-- 禁止任何应用获取 -->
    <deny permission="android.car.permission.CAR_ENGINE_CONTROL" />
</car-permissions>

再说说沙箱。Android本身就有应用沙箱机制——每个应用运行在独立的UID和进程中。但在车载上,我们还需要考虑多显示设备多用户的沙箱隔离。比如,副驾驶屏幕上的应用不能访问驾驶屏幕的数据,后排娱乐屏的应用不能控制车辆。

实现方式其实不复杂——通过显示设备ID用户ID的组合,来限制应用的资源访问范围。我在项目中用过DisplayManager + UserManager的组合,效果还不错。

个人建议:权限和沙箱这块,不要自己从头造轮子。Android 12+ 已经引入了CarServiceCarPermissionManager,很多能力可以直接复用。你只需要在它的基础上,叠加自己的业务策略即可。

知识体系总览

下面这张图,是我梳理的车载应用管理定制的核心逻辑。你可以看到,从PMS定制出发,延伸到安装策略、预装管理、权限沙箱,最终形成一个闭环。

车载应用管理定制知识体系 PackageManagerService 定制 安装来源管控 安装策略注入 预装应用管理 权限与沙箱 白名单制 签名校验 延迟/静默安装 安装队列控制 预装分区管理 卸载保护 车载权限策略 多用户沙箱 目标:安全、可控、可维护的车载应用生态

好了,这一章的内容就到这里。车载应用管理定制,说白了就是在Android原生能力的基础上,叠加车规级的安全和策略管控。PMS是核心,安装策略是手段,预装管理是基础,权限沙箱是保障。把这四块吃透了,车载应用管理这块基本就稳了。

公众号:蓝海资料掘金营,微信deep3321