Android 14 Binderized HAL开发实战指南(AIDL版)
环境要求
Android 14源码编译环境 AOSP android-14.0.0_r7
分支 Soong build系统 Java 17 & NDK r25c
项目结构
hardware/interfaces/myservice/
├── 1.0
│ ├── IMyHalService.aidl
│ └── Android.bp
├── impl
│ ├── MyHalService.cpp
│ ├── service.cpp
│ └── Android.bp
└── sepolicy└── myservice.te
完整实现步骤
1. 定义AIDL接口
// hardware/interfaces/myservice/1.0/IMyHalService.aidl
package android.hardware.myservice@1.0;@Backing(type="int")
enum ErrorCode {OK,DEVICE_BUSY,INVALID_PARAM
}interface IMyHalService {@nullableString getHardwareId();@error(ErrorCode)int sendControlCommand(in int cmdId, in byte[] payload);oneway void registerCallback(in ICallback callback);oneway void unregisterCallback(in ICallback callback);
}interface ICallback {oneway void onEvent(int eventId, in byte[] data);
}
2. 实现HAL服务
# include <android/binder_ibinder.h>
# include <aidl/android/hardware/myservice/BnMyHalService.h> using namespace aidl:: android:: hardware:: myservice; class MyHalService : public BnMyHalService {
public : ndk:: ScopedAStatus getHardwareId ( std:: string* _aidl_return) override { * _aidl_return = "MY_HAL_1.0" ; return ndk:: ScopedAStatus :: ok ( ) ; } ndk:: ScopedAStatus sendControlCommand ( int cmdId, const std:: vector< uint8_t > & payload, int * _aidl_return) override { if ( cmdId < 0 || cmdId > 255 ) { * _aidl_return = static_cast < int > ( ErrorCode:: INVALID_PARAM) ; return ndk:: ScopedAStatus :: fromExceptionCode ( EX_ILLEGAL_ARGUMENT) ; } * _aidl_return = static_cast < int > ( ErrorCode:: OK) ; return ndk:: ScopedAStatus :: ok ( ) ; } ndk:: ScopedAStatus registerCallback ( const std:: shared_ptr< ICallback> & callback) override { std:: lock_guard< std:: mutex> lock ( mMutex) ; mCallbacks. insert ( callback) ; return ndk:: ScopedAStatus :: ok ( ) ; } ndk:: ScopedAStatus unregisterCallback ( const std:: shared_ptr< ICallback> & callback) override { std:: lock_guard< std:: mutex> lock ( mMutex) ; mCallbacks. erase ( callback) ; return ndk:: ScopedAStatus :: ok ( ) ; } private : std:: mutex mMutex; std:: unordered_set< std:: shared_ptr< ICallback>> mCallbacks;
} ;
3. 服务入口实现
# include <binder/ProcessState.h>
# include <android/binder_manager.h>
# include <android/binder_process.h> using aidl:: android:: hardware:: myservice:: MyHalService; int main ( ) { ABinderProcess_setThreadPoolMaxThreadCount ( 4 ) ; std:: shared_ptr< MyHalService> service = ndk:: SharedRefBase:: make < MyHalService> ( ) ; const std:: string instance = std:: string ( ) + IMyHalService:: descriptor + "/default" ; binder_status_t status = AServiceManager_addService ( service-> asBinder ( ) . get ( ) , instance. c_str ( ) ) ; if ( status != STATUS_OK) { ALOGE ( "Failed to register service" ) ; return 1 ; } ABinderProcess_joinThreadPool ( ) ; return 0 ;
}
构建配置
接口层配置
// hardware/interfaces/myservice/1.0/Android.bp
aidl_interface {name: "android.hardware.myservice.IMyHalService",srcs: ["IMyHalService.aidl"],stability: "vintf",backend: {cpp: {enabled: true,},java: {enabled: false,},},versions: ["1"],
}
实现层配置
// hardware/interfaces/myservice/impl/Android.bp
cc_library_shared {name: "android.hardware.myservice-service",srcs: ["MyHalService.cpp","service.cpp",],shared_libs: ["android.hardware.myservice.IMyHalService","libbinder_ndk","libbase","liblog",],cflags: ["-Wall","-Werror",],
}cc_binary {name: "android.hardware.myservice@1.0-service",relative_install_path: "hw",vendor: true,init_rc: ["myservice.rc"],srcs: [":android.hardware.myservice-service"],shared_libs: ["android.hardware.myservice.IMyHalService","libbinder_ndk","libbase","liblog",],
}
SELinux配置
//myservice.te
type myservice_hwservice, hwservice_manager_type;
type myservice_default, domain;# HAL服务权限
allow myservice_default hwservicemanager:binder { call transfer };
allow myservice_default hwservicemanager:service_manager add;# 客户端权限
allow hal_client_domain myservice_hwservice:hwservice_manager { find };
VINTF配置
< hal format = " aidl" > < name> android.hardware.myservice</ name> < version> 1.0</ version> < interface> < name> IMyHalService</ name> < instance> default</ instance> </ interface>
</ hal>
客户端调用示例
// 在SystemServer中获取服务IMyHalService service = IMyHalService.Stub.asInterface(ServiceManager.waitForService("android.hardware.myservice.IMyHalService/default"));// 发送控制命令
byte[] payload = new byte[]{0x01, 0x02};
int result = service.sendControlCommand(0x20, payload);// 注册回调
service.registerCallback(new ICallback.Stub() {@Overridepublic void onEvent(int eventId, byte[] data) {// 处理硬件事件}
});