기록

[GPT가 알려주는] AIDL과 HIDL 본문

잡동사니/GPT가 알려주는

[GPT가 알려주는] AIDL과 HIDL

heylo 2025. 12. 4. 09:56
// IDdsCallback.aidl
package ivi.dds.service;

interface IDdsCallback {
	// HIDL: onReceiveData(uint32_t commandID, uint8_t channel,
	//		       uint32_t messageID, uint32_t timestamp,
	//		       vec<uint8_t> data) 와 1:1 매핑
	oneway void onReceiveData(
		int commandId, byte channel, int messageId, int timestamp, in byte[] data
	);

aidl이랑 hidl이 이해가안 돼 1:1 매핑도 이해가 안 돼
aidl이 뭐고 hidl이 뭐지? 

}

지금 보고 있는 주석은 이런 뜻이에요:

// HIDL: onReceiveData(...) 와 1:1 매핑

“위의 AIDL 메서드는 아래와 같이 정의된 HIDL 메서드
이름/파라미터/의미가 완전히 똑같다” 는 뜻

먼저 AIDL / HIDL부터 정리할게요.


1. AIDL이 뭐고 HIDL이 뭐냐?

AIDL (Android Interface Definition Language)

  • 목적:
    안드로이드에서 프로세스 간 통신(IPC)을 위해
    Java/Kotlin 쪽에서 쓰는 인터페이스 정의 언어.
  • 하는 일:
    • .aidl 파일에 메서드 시그니처를 써두면
    • 빌드 시에 자동으로 Stub / Proxy 클래스를 만들어 줌.
    • 앱이나 시스템 서비스에서 이 인터페이스를 통해
      다른 프로세스에 있는 서비스 함수를 호출할 수 있음.
  • 예: 지금 보여준 코드여기서 IDdsCallback은 Java(또는 Kotlin) 서비스/클라이언트 사이의
    콜백 인터페이스를 정의한 것.
  • // IDdsCallback.aidl package ivi.dds.service; interface IDdsCallback { oneway void onReceiveData( int commandId, byte channel, int messageId, int timestamp, in byte[] data ); }

HIDL (HAL Interface Definition Language)

  • 목적:
    예전 안드로이드에서 프레임워크(Java/C++) ↔ 벤더 HAL(C++)
    사이의 인터페이스를 정의하기 위해 만든 언어.
  • 파일 확장자: .hal
  • 예를 들면 이런 식의 인터페이스가 있음:
  • package vendor.ivi.ccs.dds.ipc@1.0; interface IDDSCallback { oneway onReceiveData( uint32_t commandID, uint8_t channel, uint32_t messageID, uint32_t timestamp, vec<uint8_t> data ); };
  • 빌드하면 C++ / Java 쪽용 Stub/Proxy 코드가 자동 생성되고,
    이걸 통해 프레임워크 코드가 벤더 C++ HAL과 통신.

지금 DDSHal.cpp에서 include 하는 것:

#include <ivi/system/ccs/dds/ipc/1.0/BpHwDDSCallback.h>

이게 바로 HIDL로 정의된 IDDSCallback의 C++ Proxy 코드에 해당해요.


2. “1:1 매핑”이 정확히 무슨 뜻?

주석에 있던 문장:

// HIDL: onReceiveData(uint32_t commandID, uint8_t channel,
//		      uint32_t messageID, uint32_t timestamp,
//		      vec<uint8_t> data) 와 1:1 매핑

이 말의 의미는:

“이 AIDL onReceiveData() 메서드는
HIDL 쪽의 onReceiveData()와 완전히 같은 의미/파라미터로 쓰인다”는 것

즉, HIDL 쪽 시그니처:

oneway onReceiveData(
    uint32_t commandID,
    uint8_t  channel,
    uint32_t messageID,
    uint32_t timestamp,
    vec<uint8_t> data
);

AIDL 쪽 시그니처:

oneway void onReceiveData(
    int commandId,      // == uint32_t
    byte channel,       // == uint8_t
    int messageId,      // == uint32_t
    int timestamp,      // == uint32_t
    in byte[] data      // == vec<uint8_t>
);

1:1로 매칭시킨다는 뜻이에요.

각 파라미터가 어떻게 대응되는지

  • commandID (uint32_t) ⟷ commandId (int)
  • channel (uint8_t) ⟷ channel (byte)
  • messageID (uint32_t) ⟷ messageId (int)
  • timestamp (uint32_t) ⟷ timestamp (int)
  • vec<uint8_t> data ⟷ byte[] data

즉,

  • 이름만 살짝 다르고 타입/역할은 동일하다.
  • 순서도 같고 의미도 같으니까,
    중간에 bridge 코드에서
    • HIDL 콜백을 받으면 → 그대로 AIDL 콜백으로 넘기거나
    • 반대로 AIDL에서 받은 걸 → HIDL로 넘길 때
  • 값을 그대로 복사해서 전달해도 된다는 걸 문서화한 주석이에요.

3. 왜 굳이 AIDL이랑 HIDL을 둘 다 쓰는 구조가 나올까?

DDS 구조를 보면 보통 이런 흐름이 있을 가능성이 높아요:

  1. C++ HAL (HIDL)
    • ::vendor::ivi::ccs::dds::ipc::V1_0::IDDSCallback 사용
    • DDSHal.cpp 같은 곳에서 콜백 호출
  2. System Service (Java/Kotlin)
    • ivi.dds.service.IDdsCallback (AIDL) 사용
    • 프레임워크 또는 시스템 앱이 이 인터페이스를 구현해서 데이터 받음
  3. 중간에 DDSManager / DDSService 같은 브리지 코드가
    • HIDL 콜백을 받고
    • 같은 내용으로 AIDL 콜백을 다시 불러줌

이때 HIDL과 AIDL의 메서드가 1:1로 딱 맞춰져 있어야
데이터를 손실 없이 그대로 전달할 수 있기 때문에
**“1:1 매핑”**이라고 써 둔 거라고 보면 됩니다.


4. ‘oneway’는 뭐냐?

둘 다 oneway가 붙어 있죠.

  • 의미: 비동기 호출
    • 호출한 쪽은 리턴값을 기다리지 않고 바로 돌아감.
    • Binder에서 FLAG_ONEWAY로 처리.
  • 콜백/이벤트 알림 같은 패턴에 많이 씀
    • DDS에서 데이터 수신 알림은 “이벤트” 성격이 강해서
    • oneway로 쏘고 끝내는 방식이 적합.

5. 요약

  • AIDL:
    Java/Kotlin (또는 NDK) 사이에서 IPC 인터페이스를 정의하는 언어.
  • HIDL:
    프레임워크 ↔ 벤더 HAL(C++) 사이 인터페이스를 정의하는 언어(구세대 HAL 방식).
  • 네 코드의 IDdsCallback.aidl은
    HIDL IDDSCallback.onReceiveData()와 동일한 구조로 맞춰서
    중간에서 그대로 값을 복사해서 전달하기 쉽게 만든 것.
  • “1:1 매핑”은
    • 메서드 이름 + 파라미터 개수/순서 + 타입 + 의미가 완전히 같다는 말.

혹시 다음 단계로,

  • “이 HIDL 콜백이 C++ 쪽에서 어디서 불리고, AIDL 쪽으로 어떻게 전달되는지 call flow 그림으로 보고 싶다”
    같은 게 필요하면, DDSHal.cpp / DDSManager.cpp / Java 서비스 파일까지 이어서 흐름도 같이 정리해 줄게요.