package {
    default_applicable_licenses: ["Android-Apache-2.0"],
}

microdroid_filesystem_images = [
    "microdroid_super",
    "microdroid_vbmeta",
]

soong_config_module_type {
    name: "virt_apex",
    module_type: "apex",
    config_namespace: "ANDROID",
    bool_variables: [
        "avf_enabled",
    ],
    properties: [
        "defaults",
    ],
}

virt_apex {
    name: "com.android.virt",
    soong_config_variables: {
        avf_enabled: {
            defaults: ["com.android.virt_avf_enabled"],
            conditions_default: {
                defaults: ["com.android.virt_avf_disabled"],
            },
        },
    },
}

apex_defaults {
    name: "com.android.virt_common",
    // TODO(jiyong): make it updatable
    updatable: false,
    future_updatable: false,
    platform_apis: true,

    manifest: "manifest.json",

    key: "com.android.virt.key",
    certificate: ":com.android.virt.certificate",

    apps: [
        "android.system.virtualmachine.res",
    ],

    file_contexts: ":com.android.virt-file_contexts",

    bootclasspath_fragments: [
        "com.android.virt-bootclasspath-fragment",
    ],
    jni_libs: [
        "libvirtualizationservice_jni",
        "libvirtualmachine_jni",
    ],
    native_shared_libs: ["libavf"],
    // TODO(b/295593640) Unfortunately these are added to the apex even though they are unused.
    // Once the build system is fixed, remove this.
    unwanted_transitive_deps: [
        "libsso",
        "libutils",
    ],

    systemserverclasspath_fragments: select(release_flag("RELEASE_AVF_ENABLE_LLPVM_CHANGES"), {
        true: ["com.android.virt-systemserver-fragment"],
        default: [],
    }),

    canned_fs_config: "canned_fs_config",
}

apex_defaults {
    name: "com.android.virt_avf_enabled",

    defaults: ["com.android.virt_common"],

    custom_sign_tool: "sign_virt_apex",

    // crosvm and virtualizationservice are only enabled for 64-bit targets on device
    arch: {
        arm64: {
            binaries: [
                "crosvm",
                "virtmgr",
                "virtualizationservice",
            ] + select(release_flag("RELEASE_AVF_ENABLE_DEVICE_ASSIGNMENT"), {
                true: ["vfio_handler"],
                default: [],
            }) + select(release_flag("RELEASE_AVF_ENABLE_NETWORK"), {
                true: ["vmnic"],
                default: [],
            }) + select(release_flag("RELEASE_AVF_ENABLE_EARLY_VM"), {
                true: ["early_virtmgr"],
                default: [],
            }),
            filesystems: microdroid_filesystem_images,
            prebuilts: [
                "service_vm_bin",
                "android_bootloader_crosvm_aarch64",
            ],
        },
        x86_64: {
            binaries: [
                "crosvm",
                "virtmgr",
                "virtualizationservice",
            ] + select(release_flag("RELEASE_AVF_ENABLE_DEVICE_ASSIGNMENT"), {
                true: ["vfio_handler"],
                default: [],
            }) + select(release_flag("RELEASE_AVF_ENABLE_NETWORK"), {
                true: ["vmnic"],
                default: [],
            }) + select(release_flag("RELEASE_AVF_ENABLE_EARLY_VM"), {
                true: ["early_virtmgr"],
                default: [],
            }),
            filesystems: microdroid_filesystem_images,
            prebuilts: [
                "android_bootloader_crosvm_x86_64",
            ],
        },
    },
    binaries: [
        "fd_server",
        "vm",
    ],
    prebuilts: [
        "microdroid_initrd_debuggable",
        "microdroid_initrd_normal",
        "microdroid.json",
        "microdroid_kernel",
        "com.android.virt.init.rc",
    ] + select(soong_config_variable("ANDROID", "avf_microdroid_guest_gki_version"), {
        "android15_66": [
            "microdroid_gki-android15-6.6_initrd_debuggable",
            "microdroid_gki-android15-6.6_initrd_normal",
            "microdroid_gki-android15-6.6_kernel",
            "microdroid_gki-android15-6.6.json",
        ],
        "android16_612": [
            "microdroid_gki-android16-6.12_initrd_debuggable",
            "microdroid_gki-android16-6.12_initrd_normal",
            "microdroid_gki-android16-6.12_kernel",
            "microdroid_gki-android16-6.12.json",
        ],
        // Internal option used by pkvm team while developing new features.
        // Should not be used on production kernels.
        "pkvm_experimental": [
            "microdroid_gki-pkvm_experimental_initrd_debuggable",
            "microdroid_gki-pkvm_experimental_initrd_normal",
            "microdroid_gki-pkvm_experimental_kernel",
            "microdroid_gki-pkvm_experimental.json",
        ],
        default: [],
    }) + select(release_flag("RELEASE_AVF_ENABLE_DEVICE_ASSIGNMENT"), {
        true: ["com.android.virt.vfio_handler.rc"],
        default: [],
    }) + select(release_flag("RELEASE_AVF_ENABLE_NETWORK"), {
        true: ["com.android.virt.vmnic.rc"],
        default: [],
    }) + select(soong_config_variable("ANDROID", "target_boots_16k"), {
        true: [
            "microdroid_16k_initrd_debuggable",
            "microdroid_16k_initrd_normal",
            "microdroid_kernel_16k",
            "microdroid_16k.json",
        ],
        default: [],
    }),
    host_required: [
        "vm_shell",
    ],
    apps: [
        "EmptyPayloadApp",
    ] + select(release_flag("RELEASE_AVF_SUPPORT_CUSTOM_VM_WITH_PARAVIRTUALIZED_DEVICES"), {
        true: [
            "VmTerminalApp",
        ],
        default: [],
    }),
    androidManifest: select(release_flag("RELEASE_AVF_ENABLE_LLPVM_CHANGES"), {
        true: "AndroidManifest.xml",
        default: unset,
    }),
}

apex_defaults {
    name: "com.android.virt_avf_disabled",

    defaults: ["com.android.virt_common"],
}

apex_key {
    name: "com.android.virt.key",
    public_key: "com.android.virt.avbpubkey",
    private_key: "com.android.virt.pem",
}

android_app_certificate {
    name: "com.android.virt.certificate",
    certificate: "com.android.virt",
}

genrule {
    name: "virtualizationservice_rc_combined",
    srcs: [
        "virtualizationservice.rc.base",
    ] + select(release_flag("RELEASE_AVF_ENABLE_LLPVM_CHANGES"), {
        true: ["virtualizationservice.rc.llpvm"],
        default: [],
    }) + select(soong_config_variable("ANDROID", "avf_remote_attestation_enabled"), {
        "true": ["virtualizationservice.rc.ra"],
        default: [],
    }),
    out: ["virtualizationservice.rc"],
    cmd: "cat $(in) > $(out)",
}

prebuilt_etc {
    name: "com.android.virt.init.rc",
    src: ":virtualizationservice_rc_combined",
    filename: "virtualizationservice.rc",
    no_full_install: true,
}

prebuilt_etc {
    name: "com.android.virt.vfio_handler.rc",
    src: "vfio_handler.rc",
    filename: "vfio_handler.rc",
    no_full_install: true,
}

prebuilt_etc {
    name: "com.android.virt.vmnic.rc",
    src: "vmnic.rc",
    filename: "vmnic.rc",
    no_full_install: true,
}

// Virt apex needs a custom signer for its payload
python_binary_host {
    name: "sign_virt_apex",
    srcs: [
        "sign_virt_apex.py",
    ],
    required: [
        // sign_virt_apex should be runnable from outside the source tree,
        // therefore, any required tool should be listed in build/make/core/Makefile as well.
        "img2simg",
        "initrd_bootconfig",
        "lpmake",
        "lpunpack",
        "lz4",
        "simg2img",
    ],
}

sh_test_host {
    name: "sign_virt_apex_test",
    src: "sign_virt_apex_test.sh",
    test_config: "sign_virt_apex_test.xml",
    data_bins: [
        // deapexer
        "deapexer",
        "debugfs_static",
        "fsck.erofs",

        // sign_virt_apex
        "avbtool",
        "img2simg",
        "initrd_bootconfig",
        "lpmake",
        "lpunpack",
        "lz4",
        "sign_virt_apex",
        "simg2img",
    ],
    data_libs: [
        "libbase",
        "libc++",
        "libcrypto_utils",
        "libcrypto",
        "libext4_utils",
        "liblog",
        "liblp",
        "libsparse",
        "libz",
    ],
    data: [
        ":test.com.android.virt.pem",
    ],
    device_common_data: [
        ":com.android.virt",
    ],
    test_suites: ["general-tests"],
}

filegroup {
    name: "test.com.android.virt.pem",
    srcs: ["test.com.android.virt.pem"],
}

filegroup {
    name: "test2.com.android.virt.pem",
    srcs: ["test2.com.android.virt.pem"],
}

// custom tool to replace bytes in a file
python_binary_host {
    name: "replace_bytes",
    srcs: [
        "replace_bytes.py",
    ],
}

// Encapsulate the contributions made by the com.android.virt to the bootclasspath.
bootclasspath_fragment {
    name: "com.android.virt-bootclasspath-fragment",
    contents: ["framework-virtualization"],
    apex_available: ["com.android.virt"],

    // The bootclasspath_fragments that provide APIs on which this depends.
    fragments: [
        {
            apex: "com.android.art",
            module: "art-bootclasspath-fragment",
        },
    ],

    // Additional stubs libraries that this fragment's contents use which are
    // not provided by another bootclasspath_fragment.
    additional_stubs: [
        "android-non-updatable",
    ],

    hidden_api: {

        // This module does not contain any split packages.
        split_packages: [],

        // The following packages and all their subpackages currently only
        // contain classes from this bootclasspath_fragment. Listing a package
        // here won't prevent other bootclasspath modules from adding classes in
        // any of those packages but it will prevent them from adding those
        // classes into an API surface, e.g. public, system, etc.. Doing so will
        // result in a build failure due to inconsistent flags.
        package_prefixes: [
            "android.system.virtualmachine",
            "android.system.virtualizationservice",
            // android.sysprop.*, renamed by jarjar
            "com.android.system.virtualmachine.sysprop",
        ],
    },
}

systemserverclasspath_fragment {
    name: "com.android.virt-systemserver-fragment",
    contents: [
        "service-virtualization",
    ],
    apex_available: ["com.android.virt"],
    enabled: select(release_flag("RELEASE_AVF_ENABLE_LLPVM_CHANGES"), {
        true: true,
        default: false,
    }),
}
