공급업체 네이티브 개발 키트(VNDK) 개요

공급업체 네이티브 개발 키트(VNDK)는 dlopen을 위해 런타임 시 공급업체 또는 제품 파티션의 다른 라이브러리나 바이너리에서 사용하는 일련의 라이브러리입니다.

디프리케이션

공급업체 NDK는 프레임워크와 공급업체 코드 간에 API를 제공하기 위해 Android 8.0에서 도입되었습니다. VNDK는 오랫동안 성공적으로 사용되어 왔지만 몇 가지 단점이 있습니다.
  • 저장용량
    • 단일 VNDK APEX는 기기에서 사용되는지 여부와 관계없이 모든 VNDK 라이브러리를 패키징합니다.
    • GSI에는 여러 버전의 공급업체 이미지를 지원하기 위한 여러 버전의 VNDK APEX가 포함되어 있습니다.
  • 업데이트 가능성
    • VNDK APEX는 플랫폼 업데이트와 별도로 업데이트하기 어렵습니다.
    • 공급업체 이미지는 무선 업데이트 (OTA)를 통해 자주 업데이트되므로 시스템 이미지 내에 VNDK를 패키징하는 이점이 줄어듭니다.
이러한 문제로 인해 Android 15부터 VNDK를 지원 중단하기로 결정했습니다.

VNDK 지원 중단에 관한 세부정보

모든 VNDK 라이브러리는 VNDK APEX에 패키징되고 시스템 (-ext) 이미지에 설치됩니다. VNDK 지원 중단으로 인해 이전 VNDK 라이브러리는 다른 공급업체 제공 라이브러리와 마찬가지로 공급업체 (또는 제품) 이미지에 설치됩니다. 다음 기능은 VNDK 지원 중단과 함께 삭제됩니다.
  • Android 15용 VNDK APEX
  • 공급업체 또는 제품 파티션이 Android 15용으로 빌드된 경우 타겟 VNDK 버전을 나타내는 시스템 속성이 삭제됩니다.
    • ro.vndk.version
    • ro.product.vndk.version
  • VNDK가 없으므로 VNDK 최적화를 사용할 수 없습니다.
    • Android Go 기기의 경우 TARGET_VNDK_USING_CORE_VARIANT
    • 공급업체 APEX의 경우 use_vndk_as_stable
  • VNDK에 크게 종속되는 공급업체 스냅샷

지원 중단 예외

VNDK 지원 중단과 함께 변경되지 않는 기능은 다음과 같습니다.
  • 기존 공급업체 이미지를 지원하는 데 필요한 VNDK 버전 14 이하의 VNDK APEX
  • LL-NDK는 VNDK의 일부가 아닙니다.

VNDK여야 하는 이유

AOSP는 공급업체 파티션을 그대로 유지한 상태에서 시스템 파티션을 최신 프레임워크 버전으로 업그레이드할 수 있는 프레임워크 전용 업데이트를 지원합니다. 다른 시점에 빌드되더라도 각 파티션의 바이너리는 서로 호환될 수 있어야 합니다.

프레임워크 전용 업데이트에는 다음과 같은 문제가 있습니다.

  • 프레임워크 모듈 및 공급업체 모듈 간의 종속 항목. Android 8.0 전에는 공급업체와 시스템 파티션의 모듈이 서로 연결될 수 있었습니다. 하지만 공급업체 모듈의 종속 항목에 따라 프레임워크 모듈 개발에 원치 않는 제한이 적용되었습니다.
  • AOSP 라이브러리 확장. Android에서는 시스템 파티션이 표준 일반 시스템 이미지(GSI)로 교체되면 모든 Android 기기가 CTS를 통과해야 합니다. 하지만 공급업체가 성능을 높이거나 HIDL 구현에 추가 기능을 더하기 위해 AOSP 라이브러리를 확장하는 과정에서 시스템 파티션을 표준 GSI로 플래시하면 공급업체의 HIDL 구현이 중단될 수 있습니다. 이러한 중단을 방지하기 위한 가이드라인은 VNDK 확장 프로그램을 참고하세요.

이러한 문제를 해결하기 위해 Android에는 VNDK(이 섹션에서 설명), HIDL, hwbinder, 기기 트리 오버레이, sepolicy 오버레이와 같은 여러 기능이 포함됩니다.

VNDK 관련 용어

VNDK 관련 문서에서는 다음과 같은 용어를 사용합니다.
  • 모듈은 공유 라이브러리 또는 실행 파일을 의미합니다. 모듈은 빌드 시간 종속 항목을 만듭니다.
  • 프로세스는 실행 파일에서 생성되는 운영체제 작업입니다. 프로세스는 런타임 종속 항목을 만듭니다.
  • 프레임워크 한정 용어는 system 파티션과 관련이 있습니다.
    • 프레임워크 실행 파일/system/bin 또는 /system/xbin에 있는 실행 파일을 의미합니다.
    • 프레임워크 공유 라이브러리/system/lib[64] 아래에 있는 공유 라이브러리를 의미합니다.
    • 프레임워크 모듈은 프레임워크 공유 라이브러리 및 프레임워크 실행 파일을 모두 의미합니다.
    • 프레임워크 프로세스/system/bin/app_process와 같은 프레임워크 실행 파일에서 생성된 프로세스입니다.
  • 공급업체 한정 용어는 vendor 파티션과 관련이 있습니다.
    • 공급업체 실행 파일/vendor/bin에 있는 실행 파일을 의미합니다.
    • 공급업체 공유 라이브러리/vendor/lib[64] 아래에 있는 공유 라이브러리를 의미합니다.
    • 공급업체 모듈은 공급업체 실행 파일 및 공급업체 공유 라이브러리를 의미합니다.
    • 공급업체 프로세스/vendor/bin/android.hardware.camera.provider@2.4-service와 같은 공급업체 실행 파일에서 생성된 프로세스입니다.

VNDK 개념

이상적인 Android 8.0 이상의 환경에서는 프레임워크 프로세스가 공급업체 공유 라이브러리를 로드하지 않고, 모든 공급업체 프로세스가 공급업체 공유 라이브러리(및 프레임워크 공유 라이브러리의 일부)만 로드하며, 프레임워크 프로세스 및 공급업체 프로세스 간의 통신이 HIDL 및 하드웨어 바인더에 의해 관리됩니다.

이러한 환경에서는 프레임워크 공유 라이브러리의 안정적인 공개 API가 공급업체 모듈 개발자에게 충분하지 않을 수 있습니다(API가 Android 출시 간에 변경될 수는 있음). 따라서 공급업체 프로세스에서 프레임워크 공유 라이브러리의 일부에 액세스할 수 있어야 합니다. 또한 성능 요구사항이 손상으로 이어질 수 있으므로 응답 시간이 중요한 일부 HAL을 다르게 취급해야 합니다.

다음 섹션에서는 VNDK가 공급업체 및 동일 프로세스 HAL(SP-HAL)의 프레임워크 공유 라이브러리를 어떻게 다루는지에 대해 설명합니다.

공급업체의 프레임워크 공유 라이브러리

이 섹션에서는 공급업체 프로세스에서 액세스 가능한 공유 라이브러리에 대한 분류 기준을 설명합니다. 여러 Android 출시에 걸쳐 공급업체 모듈을 지원하기 위한 두 가지 접근 방식이 있습니다.

  1. 프레임워크 공유 라이브러리의 ABI/API 안정화. 새로운 프레임워크 모듈과 기존 공급업체 모듈은 동일한 공유 라이브러리를 사용하여 메모리 사용량과 저장소 크기를 줄일 수 있습니다. 또한 고유한 공유 라이브러리는 여러 이중 로드 문제를 예방합니다. 하지만 안정적인 ABI/API를 유지하기에는 개발 비용이 너무 높으며, 모든 프레임워크 공유 라이브러리에서 내보낸 모든 ABI/API를 안정화하기란 비현실적입니다.
  2. 기존 프레임워크 공유 라이브러리 복사. 부채널에 대한 엄격한 제한이 수반됩니다. 이는 프레임워크 모듈 및 공급업체 모듈 간의 통신을 위한 모든 메커니즘으로 정의됩니다. 여기에는 바인더, 소켓, 파이프, 공유 메모리, 공유 파일 및 시스템 속성이 포함되며 이에 국한되지 않습니다. 통신 프로토콜이 동결되고 안정적이지 않은 이상 통신이 발생하면 안 됩니다(예: hwbinder를 통한 HIDL). 이중 로드된 공유 라이브러리도 문제를 일으킬 수 있습니다. 예를 들어 새 라이브러리에 의해 생성된 객체가 기존 라이브러리의 함수로 전달되면 이러한 라이브러리에서 객체를 다르게 해석할 수 있으므로 오류가 발생할 수 있습니다.

공유 라이브러리의 특성에 따라 다른 접근 방식이 사용됩니다. 결과적으로는 프레임워크 공유 라이브러리가 세 가지의 하위 카테고리로 분류됩니다.

  • LL-NDK 라이브러리는 안정적이라고 알려진 프레임워크 공유 라이브러리입니다. 개발자는 API/ABI 안정성 유지를 위해 최선을 다합니다.
    • LL-NDK에는 다음 라이브러리가 포함됩니다. libEGL.so, libGLESv1_CM.so, libGLESv2.so, libGLESv3.so, libandroid_net.so, libc.so, libdl.so, liblog.so, libm.so, libnativewindow.so, libneuralnetworks.so, libsync.so, libvndksupport.so, libvulkan.so
  • 사용 가능한 VNDK 라이브러리(VNDK)는 두 번 복사해도 안전한 프레임워크 공유 라이브러리입니다. 프레임워크 모듈공급업체 모듈은 자체 사본과 링크될 수 있습니다. 프레임워크 공유 라이브러리는 다음 기준을 충족하는 경우에만 사용 가능한 VNDK 라이브러리가 될 수 있습니다.
    • 프레임워크에서 IPC를 송수신하지 않습니다.
    • ART 가상 머신과 관련이 없습니다.
    • 불안정한 파일 형식으로 파일/파티션을 읽고 쓰지 않습니다.
    • 법적 검토가 필요한 특수 소프트웨어 라이선스가 없습니다.
    • 코드 소유자가 공급업체 사용에 반대하지 않습니다.
  • 프레임워크 전용 라이브러리(FWK 전용)는 위에서 언급한 카테고리에 속하지 않는 프레임워크 공유 라이브러리입니다. 이 라이브러리의 특징은 다음과 같습니다.
    • 프레임워크 내부 구현 세부정보로 간주됩니다.
    • 공급업체 모듈에서 액세스하면 안 됩니다.
    • ABI/API가 불안정하며 API/ABI 호환성이 보장되지 않습니다.
    • 복사되지 않습니다.

동일 프로세스 HAL(SP-HAL)

동일 프로세스 HAL(SP-HAL)은 공급업체 공유 라이브러리로 구현되어 프레임워크 프로세스에 로드되는 미리 정해진 HAL의 집합입니다. SP-HAL은 공유 라이브러리에 표시되는 라이브러리와 기호를 제어하는 링커 네임스페이스에 의해 격리됩니다. SP-HAL은 LL-NDKVNDK-SP에만 종속되어야 합니다.

VNDK-SP는 사용 가능한 VNDK 라이브러리의 사전 정의된 하위 집합입니다. VNDK-SP 라이브러리는 VNDK-SP 라이브러리를 프레임워크 프로세스로 이중 로드하는 과정에서 문제가 발생하지 않도록 신중히 검토됩니다. SP-HAL 및 VNDK-SP 모두 Google에서 정의합니다.

다음 라이브러리는 승인된 SP-HAL입니다.

  • libGLESv1_CM_${driver}.so
  • libGLESv2_${driver}.so
  • libGLESv3_${driver}.so
  • libEGL_${driver}.so
  • vulkan.${driver}.so
  • android.hardware.renderscript@1.0-impl.so
  • android.hardware.graphics.mapper@2.0-impl.so

VNDK-SP 라이브러리는 Android.bp 파일에 vndk: { support_system_process: true }를 지정합니다. vndk: {private:true}도 지정되어 있는 경우 이러한 라이브러리는 VNDK-SP-Private이라고 하며 SP-HALS에 표시되지 않습니다.

다음은 RS 예외가 적용된 프레임워크 전용 라이브러리(FWK-ONLY-RS)입니다.

  • libft2.so(Renderscript)
  • libmediandk.so(Renderscript)

VNDK 버전 관리

VNDK 공유 라이브러리는 다음과 같이 버전을 관리합니다.

  • ro.vndk.version 시스템 속성이 /vendor/default.prop에 자동으로 추가됩니다.
  • VNDK 및 VNDK-SP 공유 라이브러리는 VNDK apex com.android.vndk.v${ro.vndk.version}으로 설치되고 /apex/com.android.vndk.v${ro.vndk.version}에 유지됩니다.

ro.vndk.version의 값은 아래 알고리즘에 따라 선택됩니다.

  • BOARD_VNDK_VERSIONcurrent다른 경우 BOARD_VNDK_VERSION 사용
  • BOARD_VNDK_VERSIONcurrent같은 경우:
    • PLATFORM_VERSION_CODENAMEREL인 경우 PLATFORM_SDK_VERSION 사용(예: 28).
    • 아니면 PLATFORM_VERSION_CODENAME 사용(예: P).

공급업체 테스트 모음(VTS)

Android 공급업체 테스트 모음(VTS)은 비어 있지 않은 ro.vndk.version 속성을 필요로 합니다. 새로 출시된 기기와 업그레이드하는 기기 모두 ro.vndk.version을 정의해야 합니다. 일부 VNDK 테스트 사례(예를 들어 VtsVndkFilesTestVtsVndkDependencyTest)는 ro.vndk.version 속성을 사용하여 일치하는 사용 가능한 VNDK 라이브러리 데이터 세트를 로드합니다.