如何在AOSP中创建自定义HAL并从Android应用调用其方法?
在AOSP中创建自定义HAL并从Android应用访问方法的步骤
一、创建HAL的HIDL接口
- 在AOSP源码的
hardware/interfaces/目录下创建自定义HAL的目录结构:hardware/interfaces/mycustomhal/1.0/ - 在该目录下创建HIDL接口文件
IMyCustomHal.hal,定义需要暴露的方法:package android.hardware.mycustomhal@1.0; interface IMyCustomHal { getHelloString() generates (string result); setAndGetValue(int32_t input) generates (int32_t output); }; - 运行HIDL生成工具生成对应代码:
./hardware/interfaces/update-makefiles.sh
二、实现HAL服务
- 在
hardware/interfaces/mycustomhal/1.0/default/目录下创建实现文件MyCustomHal.cpp:#include <android/hardware/mycustomhal/1.0/IMyCustomHal.h> #include <hidl/LegacySupport.h> using android::hardware::mycustomhal::V1_0::IMyCustomHal; using android::hardware::Return; using android::hardware::Void; using android::sp; struct MyCustomHal : public IMyCustomHal { Return<void> getHelloString(getHelloString_cb _hidl_cb) override { _hidl_cb("Hello from Custom HAL!"); return Void(); } Return<void> setAndGetValue(int32_t input, setAndGetValue_cb _hidl_cb) override { int32_t output = input * 2; _hidl_cb(output); return Void(); } }; extern "C" IMyCustomHal* HIDL_FETCH_IMyCustomHal(const char* /* name */) { return new MyCustomHal(); } - 创建
Android.bp编译脚本:cc_library_shared { name: "android.hardware.mycustomhal@1.0-impl", relative_install_path: "hw", defaults: ["hidl_defaults"], srcs: ["MyCustomHal.cpp"], shared_libs: [ "libhidlbase", "libhidltransport", "libutils", "android.hardware.mycustomhal@1.0", ], } - 编译HAL模块:
m android.hardware.mycustomhal@1.0-impl
三、编写系统中转服务
Android应用无法直接访问HAL,需通过系统服务封装HAL方法:
- 在
frameworks/base/services/core/java/com/android/server/目录下创建服务类MyCustomService.java:package com.android.server; import android.hardware.mycustomhal.V1_0.IMyCustomHal; import android.os.RemoteException; import android.util.Slog; import java.util.NoSuchElementException; public class MyCustomService extends IMyCustomService.Stub { private static final String TAG = "MyCustomService"; private IMyCustomHal mHalService; public MyCustomService() { try { mHalService = IMyCustomHal.getService(); if (mHalService == null) { Slog.e(TAG, "Failed to get HAL service"); } } catch (NoSuchElementException | RemoteException e) { Slog.e(TAG, "Error accessing HAL: " + e.getMessage()); } } @Override public String getHelloString() throws RemoteException { return mHalService == null ? "HAL service not available" : mHalService.getHelloString(); } @Override public int setAndGetValue(int input) throws RemoteException { return mHalService == null ? -1 : mHalService.setAndGetValue(input); } } - 在
frameworks/base/core/java/android/os/创建AIDL文件IMyCustomService.aidl:package android.os; interface IMyCustomService { String getHelloString(); int setAndGetValue(int input); } - 在
SystemServer.java的startOtherServices()方法中注册服务:try { ServiceManager.addService("mycustomservice", new MyCustomService()); } catch (Throwable e) { Slog.e(TAG, "Failure starting MyCustomService", e); } - 编译系统服务模块:
m frameworks/base/services/core
四、配置权限与SELinux规则
- 在
frameworks/base/core/res/AndroidManifest.xml添加自定义权限:<permission android:name="android.permission.ACCESS_MY_CUSTOM_SERVICE" android:protectionLevel="normal" /> - 在
system/sepolicy/private/service_contexts添加服务上下文:mycustomservice u:object_r:my_custom_service:s0 - 在
system/sepolicy/private/service.te添加SELinux规则:type my_custom_service, system_api_service, system_server_service, service_manager_type; allow system_server my_custom_service:service_manager add; allow appdomain my_custom_service:service_manager find; allow appdomain my_custom_service:binder call; - 重新编译SEPolicy:
m sepolicy
五、编写Android应用访问服务
- 在应用
AndroidManifest.xml声明权限:<uses-permission android:name="android.permission.ACCESS_MY_CUSTOM_SERVICE" /> - 在应用代码中绑定服务并调用方法:
import android.os.IMyCustomService; import android.os.ServiceManager; import android.util.Log; // 获取服务实例 IMyCustomService service = IMyCustomService.Stub.asInterface(ServiceManager.getService("mycustomservice")); if (service != null) { try { String hello = service.getHelloString(); Log.d("CustomHalApp", "HAL response: " + hello); int result = service.setAndGetValue(10); Log.d("CustomHalApp", "Set and get result: " + result); } catch (RemoteException e) { Log.e("CustomHalApp", "Error calling service: " + e.getMessage()); } }
六、验证调试
- 刷入编译好的系统镜像到设备
- 运行应用,通过Logcat查看输出确认调用结果
- 若遇权限问题,检查SELinux规则和权限声明是否配置正确
内容的提问来源于stack exchange,提问作者Nishant raj
相关产品推荐
相关产品推荐

