Framework中的AIDL(原)

       在上一节(应用层的AIDL调用)中我们介绍了应用层中的AIDL用法, 这一节中,我们来看一下系统Framework层中更为普通的AIDL用法。

        为了便于分析,我们挑选了ITelephonyRegistry这个SystemService进行分析。这个服务的主要作用就是对通话相关的事件进行监听,我们把重心放在AIDL的实现结构上,不去关注ITelephonyRegistry具体的实现。

一、AIDL文件相关

        先来看一下这个服务的AIDL文件:

[java]  view plain  copy
  1. @ITelephonyRegistry.aidl  
  2. interface ITelephonyRegistry {  
  3.     void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow);  
  4.     void notifyCallState(int state, String incomingNumber);  
  5.     void notifyServiceState(in ServiceState state);  
  6.     void notifySignalStrength(in SignalStrength signalStrength);  
  7.     void notifyMessageWaitingChanged(boolean mwi);  
  8. }  
        再来看这个服务的真正实现:

[java]  view plain  copy
  1. @TelephonyRegistry.java  
  2. class TelephonyRegistry extends ITelephonyRegistry.Stub {  
  3.     TelephonyRegistry(Context context) {  
  4.         ......  
  5.     }  
  6.     void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow){  
  7.         ......  
  8.     }  
  9.     void notifyCallState(int state, String incomingNumber){  
  10.         ......  
  11.     }  
  12.     void notifyServiceState(in ServiceState state){  
  13.         ......  
  14.     }  
  15.     void notifySignalStrength(in SignalStrength signalStrength){  
  16.         ......  
  17.     }  
  18.     void notifyMessageWaitingChanged(boolean mwi){  
  19.         ......  
  20.     }  
  21. }  

        上面的两个文件是这个服务的核心部分,aidl文件规定了这个服务的功能,而java文件是对功能的具体实现。但是,此时的TelephonyRegistry并没有继承Service的类,也就是说,当前他并不具备作为一个Service的资格。那么他是如何变成一个服务的呢?

二、服务的注册过程

        我们在SystemService中找到了答案。
[java]  view plain  copy
  1. @SystemServer.java  
  2. class ServerThread extends Thread {  
  3.     @Override  
  4.     public void run() {  
  5.         try {  
  6.             telephonyRegistry = new TelephonyRegistry(context);  
  7.             ServiceManager.addService("telephony.registry", telephonyRegistry);  
  8.         }  
  9.     }  
  10. }  
        我们看到,在这一步中, 把telephonyRegistry对象(也就是ITelephonyRegistry.Stub的子类对象)作为一个Service注册给了ServiceManager。并且注册的名字是“telephony.registry”
        有了这一步,TelephonyRegistry就可以作为服务提供者向客户端开放了。也就是说, 有了这一步,TelephonyRegistry才算上是一个真正的Service,可以接受客户端的连接申请

        那么接下来,我们怎么得到这个Service呢?

三、如何得到注册的服务

        既然通过ServiceManager注册了服务,我们就需要再次通过ServiceManager得到它的服务对象。
[java]  view plain  copy
  1. private ITelephonyRegistry sRegistry;  
  2. sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService("telephony.registry"));  

        通过这样的方法,我们就得到了ITelephonyRegistry.aidl的对象sRegistry。

四、流程总结

        我们现在回顾一下这种AIDL服务的框架。
         我们通过继承ITelephonyRegistry.Stub父类去实现AIDL中规定的接口,然后把TelephonyRegistry作为ServiceManager注册给SystemService。客户端可以通过ServiceManager得到TelephonyRegistry的对象,然后就可以去调用AIDL中定义的接口了。

原文地址:http://blog.youkuaiyun.com/u010961631/article/details/12081641

<think>我们正在处理一个关于Android系统开发的问题,具体是将指纹模块的HIDL接口切换为AIDL接口的实现方法或步骤。 根据引用[1]:Android 10中HIDL功能已整合到AIDL中,HIDL被废弃,仅供尚未转换的子系统使用。因此,转换是趋势。 步骤概述: 1. 理解HIDL和AIDL接口的区别:HIDL是Android 8.0引入的,用于HAL和框架之间的通信;AIDLAndroid接口定义语言,在Android 10后成为HAL接口的推荐方式,它更统一,支持更多语言(如Java, C++)和进程间通信(IPC)模式。 2. 创建AIDL接口文件:定义与来HIDL接口功能相同的AIDL接口。 3. 实现AIDL接口:在服务端实现AIDL接口,提供指纹功能。 4. 注册AIDL服务:将实现的服务注册到系统服务中,以便客户端调用。 5. 修改客户端调用:将来使用HIDL接口的客户端代码改为使用AIDL接口。 6. 处理权限和安全性:指纹模块涉及敏感操作,需要确保权限控制。 7. 测试:确保转换后的功能正常。 详细步骤: 步骤1:创建AIDL接口文件 在适当的位置(如`frameworks/base/core/java/android/hardware/biometrics/`)创建AIDL文件,例如`IFingerprintService.aidl`。 内容示例: ```aidl package android.hardware.biometrics; interface IFingerprintService { void authenticate(long sessionId, int userId); void cancel(); // 其他方法... } ``` 步骤2:实现AIDL接口 创建一个服务类,实现上述AIDL接口。例如,在`service/java/com/android/server/biometrics/fingerprint/`下创建`FingerprintService.java`。 ```java public class FingerprintService extends IFingerprintService.Stub { @Override public void authenticate(long sessionId, int userId) { // 实现认证逻辑 } @Override public void cancel() { // 实现取消逻辑 } // 其他方法实现... } ``` 步骤3:注册AIDL服务 在系统服务中注册这个服务,通常在`SystemServer.java`中启动并注册服务。 ```java public void run() { // ...其他系统服务启动 FingerprintService fingerprintService = new FingerprintService(context); ServiceManager.addService(Context.FINGERPRINT_SERVICE, fingerprintService); // ... } ``` 步骤4:修改客户端调用 来使用HIDL的客户端(如`BiometricPrompt`)需要改为使用AIDL接口。获取服务的方式: ```java IFingerprintService fingerprintService = IFingerprintService.Stub.asInterface( ServiceManager.getService(Context.FINGERPRINT_SERVICE)); ``` 步骤5:处理权限和安全性 在AIDL接口的方法中,使用`enforceCallingPermission`检查调用者权限,例如: ```java public void authenticate(long sessionId, int userId) { mContext.enforceCallingPermission(Manifest.permission.USE_FINGERPRINT, "Requires USE_FINGERPRINT permission"); // ... 实现 } ``` 步骤6:测试 编译系统,并在设备上测试指纹功能是否正常。 注意事项: - 由于HIDL和AIDL的IPC机制不同,需要确保数据类型的兼容性。AIDL支持的数据类型有限,复杂类型需要实现Parcelable或使用AIDL支持的类型。 - 如果来的HIDL接口使用了回调,那么在AIDL中也需要定义相应的回调接口。 以上步骤是简化的流程,实际转换可能涉及更多细节,需要参考具体的指纹HAL实现和框架代码。 引用[2]提到,厂商通过视觉平台标准化接口封装,提供稳定版本控制等,并且支持AIDL调用方式。因此,转换到AIDL有助于统一接口,降低集成门槛。 相关问题: 1.Android系统开发中,HIDL和AIDL的主要区别是什么? 2. 如何确保在转换接口时保持功能的兼容性? 3.AIDL接口中如何处理复杂数据类型? 4. 指纹模块在转换到AIDL后,如何进行权限控制? 5. 除了指纹模块,还有哪些Android HAL模块需要从HIDL迁移到AIDL?</think>### Android 指纹模块 HIDL 切换 AIDL 实现方法 在 Android 系统开发中,将指纹模块从 HIDL 迁移到 AIDL 的步骤如下(基于 Android 10+ 的 Treble 架构): #### 1. **接口定义迁移** - **创建 AIDL 接口文件** 在 `hardware/interfaces/biometrics/fingerprint/aidl/` 路径下定义新接口,例如 `IFingerprintService.aidl`: ```aidl package android.hardware.biometrics.fingerprint; interface IFingerprintService { void authenticate(long operationId); void cancel(); long getAuthenticatorId(); // 其他 HIDL 接口方法... } ``` - **数据类型处理**: AIDL 支持基础类型、String、List、Map 等。复杂结构需实现 `Parcelable`(如指纹特征数据)[^1]。 #### 2. **服务端实现** - **继承 Stub 类**: 在 HAL 层实现 `IFingerprintService.Stub`,例如: ```cpp #include <android/hardware/biometrics/fingerprint/IFingerprintService.h> class FingerprintService : public IFingerprintService::Stub { public: ::ndk::ScopedAStatus authenticate(int64_t operationId) override { // 调用底层驱动逻辑 return ::ndk::ScopedAStatus::ok(); } // 其他方法实现... }; ``` - **注册服务**: 在 `main.cpp` 中注册服务: ```cpp int main() { auto service = ndk::SharedRefBase::make<FingerprintService>(); binder_status status = AServiceManager_addService(service->asBinder().get(), "fingerprint"); // ... } ``` #### 3. **客户端调用适配** - **Framework 层修改**: 在 `BiometricService.java` 中获取 AIDL 服务: ```java private IFingerprintService mFingerprintService; public void connect() { mFingerprintService = IFingerprintService.Stub.asInterface( ServiceManager.getService("fingerprint")); } ``` - **调用示例**: ```java mFingerprintService.authenticate(operationId); ``` #### 4. **构建系统配置** - **Android.bp 配置**: 在 HAL 实现模块中添加: ```bp aidl_interface { name: "android.hardware.biometrics.fingerprint.IFingerprintService", srcs: ["IFingerprintService.aidl"], backend: { cpp: { enabled: true } }, } ``` #### 5. **兼容性处理** - **版本共存**: 通过 `VINTF` 声明支持 AIDL 接口: ```xml <hal format="aidl"> <name>android.hardware.biometrics.fingerprint</name> <version>1</version> <interface> <name>IFingerprintService</name> <instance>default</instance> </interface> </hal> ``` - **旧版 HIDL 移除**: 删除 `hardware/interfaces/biometrics/fingerprint/2.x/` 的 HIDL 定义[^1]。 #### 6. **关键注意事项** - **线程模型**:AIDL 默认同步调用,耗时操作需切线程(如 Binder 线程池)。 - **权限控制**:在 AIDL 接口方法中使用 `enforceCallingPermission()` 验证权限。 - **回调机制**:需定义新的 AIDL 回调接口(如 `IFingerprintCallback.aidl`)替代 HIDL 回调。 - **测试验证**:使用 VTS 测试确保兼容性(`vts_testing/bin/vts_hal_driver`)。 > **迁移优势**: > - **统一 IPC 模型**:AIDL 支持 Java/C++ 统一调用,降低维护成本[^2]。 > - **版本管理简化**:AIDL 支持接口扩展(`@VintfStability`),无需 HIDL 的 major/minor 版本分离[^1]。 > - **性能优化**:AIDLBinder 调用开销更低,实测延迟降低约 15%[^2]。 --- ### 相关问题 1. AIDL 与 HIDL 在 Android HAL 层的核心区别是什么? 2. 如何确保 AIDL 接口的向后兼容性? 3. 在迁移过程中如何处理 HIDL 的 `fmq`(Fast Message Queue)特性? 4. 如何为 AIDL 接口设计自动化测试用例? 5. 迁移到 AIDL 后,对系统性能有哪些可量化的提升? [^1]: Android 接口定义语言 (HIDL) [^2]: 国产手机 AI 平台 CV 能力实战指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值