You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为无头设备构建无显示屏/GUI的Android 10 AOSP

Android 10无头系统:添加虚拟显示适配器实现无屏运行

核心结论

完全可以在Android 10中通过添加虚拟显示适配器,实现无物理显示屏/触摸屏环境下的完整Android栈运行,替代原生DISPLAY模块的功能。

实现思路

  1. 定制虚拟显示HAL驱动:实现符合Android显示HAL规范的虚拟显示模块,让系统识别为合法的主显示设备
  2. 系统配置适配:禁用物理显示相关配置,强制系统加载虚拟显示模块
  3. 服务兼容性适配:确保WindowManager等核心服务能正确初始化并绑定虚拟显示

参考代码与配置示例

1. 虚拟显示HAL实现(hardware/libhardware/modules/virtualdisplay/VirtualDisplay.cpp)

#include <hardware/hardware.h>
#include <hardware/display.h>
#include <cutils/log.h>
#include <string.h>

static int virtual_display_close(hw_device_t* dev) {
    free(dev);
    return 0;
}

static int get_display_type(const display_device_t* dev) {
    return DISPLAY_TYPE_VIRTUAL;
}

static int get_display_size(const display_device_t* dev, uint32_t* width, uint32_t* height) {
    // 自定义虚拟显示分辨率
    *width = 1920;
    *height = 1080;
    return 0;
}

static int get_display_dpi(const display_device_t* dev, uint32_t* xdpi, uint32_t* ydpi) {
    *xdpi = 320;
    *ydpi = 320;
    return 0;
}

static int set_power_mode(display_device_t* dev, int mode) {
    // 虚拟显示无需实际电源控制,直接返回成功
    return 0;
}

static int virtual_display_open(const hw_module_t* module, const char* name, hw_device_t** device) {
    if (strcmp(name, DISPLAY_PRIMARY) != 0) {
        return -EINVAL;
    }

    display_device_t* dev = (display_device_t*)malloc(sizeof(display_device_t));
    memset(dev, 0, sizeof(display_device_t));

    dev->common.tag = HARDWARE_DEVICE_TAG;
    dev->common.version = DISPLAY_DEVICE_API_VERSION_1_0;
    dev->common.module = (hw_module_t*)module;
    dev->common.close = virtual_display_close;

    dev->get_display_type = get_display_type;
    dev->get_display_size = get_display_size;
    dev->get_display_dpi = get_display_dpi;
    dev->set_power_mode = set_power_mode;
    // 其他未实现的方法可留空,系统会处理默认逻辑

    *device = &dev->common;
    return 0;
}

static struct hw_module_methods_t virtual_display_module_methods = {
    .open = virtual_display_open,
};

struct display_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = DISPLAY_MODULE_API_VERSION_1_0,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = DISPLAY_HARDWARE_MODULE_ID,
        .name = "Virtual Display HAL",
        .author = "Custom Vendor",
        .methods = &virtual_display_module_methods,
    },
};

2. 模块编译配置(hardware/libhardware/modules/virtualdisplay/Android.mk)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE := virtualdisplay.default
LOCAL_SRC_FILES := VirtualDisplay.cpp
LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware
LOCAL_MODULE_TAGS := optional

include $(BUILD_SHARED_LIBRARY)

3. 设备配置修改(device/[vendor]/[device]/device.mk)

# 替换默认显示模块为虚拟显示
PRODUCT_PACKAGES += virtualdisplay.default

# 强制系统使用虚拟显示
PRODUCT_PROPERTY_OVERRIDES += \
    ro.hardware.display=virtualdisplay \
    ro.boot.display=virtualdisplay \
    ro.display.default_width=1920 \
    ro.display.default_height=1080

# 禁用触摸屏相关模块(按需)
PRODUCT_PACKAGES := $(filter-out touchscreen.% inputflinger,$(PRODUCT_PACKAGES))

验证方式

编译刷入系统后,通过adb命令确认虚拟显示状态:

adb shell dumpsys display

输出中应显示mDisplayType=VIRTUAL的主显示设备,且系统服务正常启动。

内容的提问来源于stack exchange,提问作者Bhaskar Naik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:36:32