全称:
Hardware Interface Definition Language
目的:
使 Android 可以在不重新编译 HAL 的情况下对 Framework 进行 OTA 升级。
基本用法
package android.hardware.audio@2.0; // 当前package包名
import android.hardware.audio.common@2.0; // 导入其它package包
import IDevice; // 导入其它.hal
interface IDevicesFactory { // 定义一个interface
typedef android.hardware.audio@2.0::Result Result;
enum Device : int32_t { // 定义数据类型
PRIMARY,
A2DP,
USB,
R_SUBMIX,
STUB
};
/**
* Opens an audio device. To close the device, it is necessary to release
* references to the returned device object.
*
* @param device device type.
* @return retval operation completion status. Returns INVALID_ARGUMENTS
* if there is no corresponding hardware module found,
* NOT_INITIALIZED if an error occured while opening the hardware
* module.
* @return result the interface for the created device.
*/
openDevice(Device device) generates (Result retval, IDevice result); // 定义一个方法
};
组织结构
以platform/hardware/interfaces/audio为例
Android.bp ----
Android.mk ---makefile 文件
IDevice.hal
IDevicesFactory.hal
IPrimaryDevice.hal
IStream.hal 具体的接口定义
IStreamIn.hal
IStreamOutCallback.hal
IStreamOut.hal
types.hal ---定义了这个包里所有 interface 共享的用户自定义数据类型,并且一般也会导入需要用到的其它包里的数据类型
Vts ---- VTS测试相关内容
由 Google 提供的包叫做core package,包名始终以android.hardware.开头,以子系统名加以区分。比如 NFC 包的名字就应该为android.hardware.nfc,摄像头包的名字就应该为android.hardware.camera。这些 core包存放于hardware/interfaces/目录下。
由各芯片厂商和 ODM厂商提供的包叫做non-core package,包名形式一般以vendor.$(vendorName).hardware.开头,比如vendor.samsung.hardware.。这些 non-core包一般存放于vendor/$(vendorName)/interfaces/目录下。
包的版本使用主、次版本号进行描述,紧随包名之后。比如[email protected]表述这个 audio 包的版本是 2.0,主版本号是 2,次版本号是 0。
此外,每个 HIDL 包在被发布后就不能再对其内容进行变动了,如果要增加或修改这个包里的接口或数据类型,应该新建一个新版本的包,在这个新版本的包里进行变更。
1.定义接口
package android.hardware.tests.foo@1.0;
interface ISimpleTest {
struct Goober {
int32_t q;
string name;
};
myhandle() generates (handle str);
};
将文件保存在hardware/interfaces/tests/foo/1.0/ISimpleTest.hal
2.HIDL编译
在根目录执行./hardware/interfaces/update-makefiles.sh
Service端的注册:
platform/hardware/interfaces/audio/2.0/default/service.cpp
int main(int /* argc */, char* /* argv */ []) {
configureRpcThreadpool(16, true /*callerWillJoin*/);
android::status_t status;
status = registerPassthroughServiceImplementation();
LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio service: %d", status);
status = registerPassthroughServiceImplementation();
LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio effects service: %d", status);
// Soundtrigger and FM radio might be not present.
status = registerPassthroughServiceImplementation();
ALOGE_IF(status != OK, "Error while registering soundtrigger service: %d", status);
if (useBroadcastRadioFutureFeatures) {
status = registerPassthroughServiceImplementation<
broadcastradio::V1_1::IBroadcastRadioFactory>();
} else {
status = registerPassthroughServiceImplementation<
broadcastradio::V1_0::IBroadcastRadioFactory>();
}
ALOGE_IF(status != OK, "Error while registering fm radio service: %d", status);
joinRpcThreadpool();
return status;
}
或者如nfc模块那样,添加一个.rc文件,让init在开机阶段即将服务启动起来
service nfc_hal_service /vendor/bin/hw/android.hardware.nfc@1.0-service
class hal
user nfc
group nfc
Client端
foo = IFoo::getService(“foo”, mode == PASSTHROUGH /* getStub */);
这里使用的是Ixxx里自动生成的 getService函数,拿到之后就能使用.hal定义的接口了。