Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

HAL용 AIDL

Android 11은 Android에서 HAL용 AIDL을 사용할 수 있는 기능을 제공합니다. 이를 사용하면 HIDL 없이도 Android의 일부를 구현할 수 있습니다. 가능한 경우 HAL을 전환하여 AIDL을 독점적으로 사용하는 것이 좋습니다(업스트림 HAL에서 HIDL을 사용하면 반드시 HIDL을 사용해야 함).

system.img의 경우와 같은 프레임워크 구성요소 및 vendor.img의 경우와 같은 하드웨어 구성요소 간에 커뮤니케이션하는 HAL은 안정적 AIDL을 사용해야 합니다. 하지만 특정 HAL에서 다른 HAL로 커뮤니케이션하는 것과 같이 파티션 내에서 커뮤니케이션할 때는 사용되는 IPC 메커니즘에 제한사항이 없습니다.

동기

AIDL은 HIDL보다 오래 되었으며 Android 프레임워크 구성요소 간이나 앱 내부 등 많은 곳에 사용됩니다. 이제 AIDL의 안정성이 지원되므로 단일 IPC 런타임으로 전체 스택을 구현할 수 있습니다. AIDL에는 HIDL보다 더 나은 버전 관리 시스템이 있습니다.

  • 단일 IPC 언어를 사용하게 되어 한 가지만 학습, 디버그, 최적화, 보호하면 됩니다.
  • AIDL은 인터페이스 소유자가 실행 중인 버전 관리를 지원합니다.
    • 소유자는 인터페이스 끝부분에 메서드를 추가하거나 parcelable에 필드를 추가할 수 있습니다. 이에 따라 시간이 지나면서 더 간편하게 코드의 버전을 관리할 수 있으며, 유형을 바로 수정할 수 있고 인터페이스 버전별로 라이브러리를 추가하지 않아도 되므로 전년 대비 비용이 감소합니다.
    • 확장 인터페이스는 유형 시스템이 아닌 런타임에 첨부할 수 있으므로 새 버전의 인터페이스에 다운스트림 확장을 리베이스하지 않아도 됩니다.
  • 소유자가 안정화하도록 선택하면 기존 AIDL 인터페이스를 직접 사용할 수 있습니다. 이렇게 하려면 전체 인터페이스 사본이 HIDL로 제작되어야 합니다.

AIDL HAL 인터페이스 작성

AIDL 인터페이스를 시스템 및 공급업체 간에 사용하려면 인터페이스의 다음 두 가지를 변경해야 합니다.

  • 모든 유형 정의에 @VintfStability로 주석을 추가해야 함
  • aidl_interface 선언에 stability: "vintf",를 포함해야 함

인터페이스 소유자만 이와 같이 변경할 수 있습니다.

또한, 코드 이동성을 최대화하고 불필요한 추가 라이브러리와 같은 잠재적인 문제를 방지하려면 CPP 백엔드를 사용 중지하는 것이 좋습니다.

    aidl_interface: {
        ...
        backends: {
            cpp: {
                enabled: false,
            },
        },
    }

AIDL HAL 인터페이스 찾기

HAL용 AOSP 안정적 AIDL 인터페이스는 HIDL 인터페이스와 동일한 기본 디렉터리인 aidl 폴더에 있습니다.

  • hardware/interfaces
  • frameworks/hardware/interfaces
  • system/hardware/interfaces

확장 인터페이스는 vendor 또는 hardware의 다른 hardware/interfaces 하위 디렉터리에 두어야 합니다. 모든 기기 간에 일관된 인터페이스를 유지하는 것이 좋습니다. 확장은 두 가지 방법으로 등록할 수 있습니다.

  • 런타임: 첨부된 확장을 참조하세요.
  • 독립형: 전역과 VINTF에 등록됩니다.

AIDL 런타임에 따라 구축하기

AIDL에는 3가지의 백엔드가 있으며 자바, NDK, CPP입니다. 안정적 AIDL을 사용하려면 항상 system/lib*/libbinder.so에 있는 libbinder의 시스템 사본을 사용하고 /dev/binder에서 대화해야 합니다. 공급업체 이미지의 코드의 경우 이는 VNDK의 libbinder를 사용할 수 없음을 의미합니다. 이 라이브러리에는 불안정한 C++ API 및 불안정한 내부 요소가 포함되어 있습니다. 대신 기본 공급업체 코드는 AIDL의 NDK 백엔드, libbinder_ndk에 연결되는 링크(시스템 libbinder.so에서 지원됨), aidl_interface 입력값에 의해 생성된 -ndk_platform 라이브러리로 연결되는 링크를 사용해야 합니다.

AIDL HAL 서버 인스턴스 이름

규칙에 따라 AIDL HAL 서비스는 $package.$type/$instance 형식의 인스턴스 이름을 갖습니다. 예를 들어 바이브레이터 HAL의 인스턴스는 android.hardware.vibrator.IVibrator/default로 등록됩니다.

AIDL HAL 서버 작성

AIDL 서버는 VINTF 매니페스트에 선언되어야 하며 예를 들면 다음과 같습니다.

    <hal format="aidl">
        <name>android.hardware.vibrator</name>
        <fqname>IVibrator/default</fqname>
    </hal>

그렇지 않으면 AIDL 서비스를 정상적으로 등록해야 합니다. VTS 테스트를 실행할 때 모든 선언된 AIDL HAL이 사용 가능한 것으로 예상됩니다.

AIDL 클라이언트 작성

AIDL 클라이언트는 다음과 같이 호환성 매트릭스에서 스스로 선언해야 합니다.

    <name>android.hardware.vibrator</name>
    <interface>
        <name>IVibrator</name>
        <instance>default</instance>
    </interface>

기존 HAL을 HIDL에서 AIDL로 변환

HIDL 인터페이스를 AIDL로 변환하려면 hidl2aidl 도구를 사용하세요. .hal 파일 패키지를 .aidl 파일로 변환하려면 다음 단계를 따르세요.

  1. system/tools/hidl/hidl2aidl에 있는 도구를 빌드합니다.

    m hidl2aidl
    
  2. 출력 디렉터리 다음에 변환할 패키지를 추가하여 도구를 실행합니다.

    hidl2aidl -o <output directory> <package>
    

    예:

    hidl2aidl -o . android.hardware.nfc@1.2
    
  3. 생성된 파일을 자세히 읽어보고 변환 관련 문제를 해결합니다.

    • conversion.log에 먼저 해결해야 하는 처리되지 않은 문제가 포함됩니다.
    • 생성된 .aidl 파일에 조치가 필요한 경고 및 추천이 있을 수 있습니다. 이 댓글은 //로 시작합니다.
    • 패키지를 정리하고 개선할 수 있습니다.

AIDL HAL용 sepolicy

공급업체 코드에 표시되는 AIDL 서비스 유형에는 vendor_service 속성이 있어야 합니다. 이 속성이 없는 경우 sepolicy 구성은 다른 AIDL 서비스와 동일합니다.

    type hal_power_service, service_manager_type, vendor_service;

플랫폼에 정의된 대부분의 서비스에는 올바른 유형의 서비스 컨텍스트가 이미 추가되어 있습니다(예: android.hardware.power.IPower/default는 이미 hal_power_service로 표시되어 있음). 그러나 프레임워크 클라이언트가 여러 인스턴스 이름을 지원하는 경우 추가 인스턴스 이름을 기기별 service_contexts 파일에 추가해야 합니다.

    android.hardware.power.IPower/custom_instance u:object_r:hal_power_service:s0

첨부된 확장 인터페이스

확장은 서비스 관리자에 직접 등록된 최상위 인터페이스이든 하위 인터페이스이든 모든 바인더 인터페이스에 첨부될 수 있습니다. 확장을 가져올 때는 확장의 유형이 예상한 것인지 확인해야 합니다. 확장은 바인더를 제공하는 프로세스에서만 설정할 수 있습니다.

첨부된 확장은 확장에서 기존 HAL의 기능을 수정할 때마다 사용되어야 합니다. 완전히 새로운 기능이 필요한 경우 이 메커니즘을 사용할 필요가 없으며 확장 인터페이스를 서비스 관리자에 직접 등록할 수 있습니다.

바인더에 확장을 설정하려면 다음 API를 사용합니다.

  • NDK 백엔드: AIBinder_setExtension
  • 자바 백엔드: android.os.Binder.setExtension
  • CPP 백엔드: android::Binder::setExtension

바인더에 확장을 가져오려면 다음 API를 사용합니다.

  • NDK 백엔드: AIBinder_getExtension
  • 자바 백엔드: android.os.IBinder.getExtension
  • CPP 백엔드: android::IBinder::getExtension

이러한 API에 관한 자세한 내용은 상응하는 백엔드의 getExtension 함수 문서에서 확인할 수 있습니다. 확장 프로그램을 사용하는 방법의 예는 hardware/interfaces/tests/extension/vibrator에서 확인할 수 있습니다.

AIDL/HIDL 주요 차이점

AIDL HAL을 사용하거나 AIDL HAL 인터페이스를 사용할 때 HIDL HAL 작성과의 차이점에 유념하세요.

  • AIDL 언어의 구문은 자바와 비슷하고 HIDL 구문은 C++와 유사합니다.
  • 모든 AIDL 인터페이스에는 내장된 오류 상태가 있습니다. 맞춤 상태 유형을 생성하는 대신 인터페이스 파일에서 상수 상태 int를 생성하고 CPP/NDK 백엔드에 있는 EX_SERVICE_SPECIFIC 및 자바 백엔드에 있는 ServiceSpecificException을 사용합니다.
  • AIDL은 확인되지 않은 전송 오류로 취소되지 않습니다(HIDL Return은 확인되지 않은 오류로 취소됨).
  • AIDL은 파일당 하나의 유형만 선언할 수 있습니다.
  • AIDL 인수는 출력 매개변수와 함께 in/out/inout으로 지정할 수 있습니다('동기식 콜백'은 없음).
  • AIDL은 핸들 대신 fd를 기본형으로 사용합니다.
  • HIDL은 호환되지 않는 변경사항에는 주 버전을 사용하고 호환되는 변경사항에는 부 버전을 사용합니다. AIDL에서는 하위 호환성 변경사항이 적용됩니다. AIDL에는 주 버전에 관한 명시적인 개념이 없으며 대신 패키지 이름에 통합됩니다. 예를 들어 AIDL은 패키지 이름 bluetooth2를 사용할 수 있습니다.