AIDL Hal 开发笔记6----添加硬件访问服务

目录

  • [一、定义 AIDL](#一、定义 AIDL)
    • [1.1 接口定义](#1.1 接口定义)
    • [1.2 接口默认空实现](#1.2 接口默认空实现)
    • [1.3 服务端 Stub 类的实现](#1.3 服务端 Stub 类的实现)
    • [1.4 代理类 Proxy 的实现](#1.4 代理类 Proxy 的实现)
  • [二、硬件服务 Server 端](#二、硬件服务 Server 端)
  • [三、硬件服务 Client 端](#三、硬件服务 Client 端)
  • [四、App 访问硬件服务](#四、App 访问硬件服务)
  • [五、Selinux 配置](#五、Selinux 配置)
    • [5.1 `service_contexts`](#5.1 service_contexts)
    • [5.2 `service.te`](#5.2 service.te)
    • [5.3 `system_app.te`](#5.3 system_app.te)
  • 六、编译运行

|--------------|
| 添加硬件访问服务 |

一、定义 AIDL

创建 aidl 文件 frameworks/base/core/java/android/hardware/hello/IHelloManager.aidl

java 复制代码
package android.hardware.hello;

/**
 * {@hide}
 */
interface IHelloManager{
    void hellohal_write(String str);
    String hellohal_read();
}

下面的 Android.bp 已经包含了该目录下几乎所有 aidl 文件和 java 文件的编译,所以我们不需要再将自定义的 IHelloManager.aidl 添加到编译环境

c 复制代码
// frameworks/base/core/java/Android.bp
filegroup {
    name: "framework-core-sources",
    srcs: [                                                                                                                                                                                                            
        "**/*.java",
        "**/*.aidl",
    ],  
    exclude_srcs: [
        // Remove election toolbar code from build time
        "android/service/selectiontoolbar/*.aidl",
        "android/service/selectiontoolbar/*.java",
        "android/view/selectiontoolbar/*.aidl",
        "android/view/selectiontoolbar/*.java",
        "com/android/internal/widget/floatingtoolbar/RemoteFloatingToolbarPopup.java",
    ],
    visibility: ["//frameworks/base"],
}

接着编译:

c 复制代码
source build/envsetup.sh
lunch xxx
make update-api
make framework-minus-apex -j32

然后再 out 目录下搜索:

c 复制代码
out$ find ./ -name "IHelloManager*"
./soong/.intermediates/frameworks/base/module-lib-api-stubs-docs-non-updatable/android_common/gen/aidl/frameworks/base/core/java/android/hardware/hello/IHelloManager.aidl.d
./soong/.intermediates/frameworks/base/framework-minus-apex/android_common/gen/aidl/frameworks/base/core/java/android/hardware/hello/IHelloManager.aidl.d
./soong/.intermediates/frameworks/base/framework-minus-apex/android_common/javac/shard33/classes/android/hardware/hello/IHelloManager$Stub$Proxy.class
./soong/.intermediates/frameworks/base/framework-minus-apex/android_common/javac/shard33/classes/android/hardware/hello/IHelloManager$Default.class
./soong/.intermediates/frameworks/base/framework-minus-apex/android_common/javac/shard33/classes/android/hardware/hello/IHelloManager.class
./soong/.intermediates/frameworks/base/framework-minus-apex/android_common/javac/shard33/classes/android/hardware/hello/IHelloManager$Stub.class
./soong/.intermediates/frameworks/base/system-api-stubs-docs-non-updatable/android_common/gen/aidl/frameworks/base/core/java/android/hardware/hello/IHelloManager.aidl.d
./soong/.intermediates/frameworks/base/api-stubs-docs-non-updatable/android_common/gen/aidl/frameworks/base/core/java/android/hardware/hello/IHelloManager.aidl.d
./soong/.intermediates/frameworks/base/test-api-stubs-docs-non-updatable/android_common/gen/aidl/frameworks/base/core/java/android/hardware/hello/IHelloManager.aidl.d

不同于之前的版本生成 java 源文件,这里生成的都是 class 文件,可以用你喜欢的反编译工具来查看具体的源码(我使用的是 vscode 的插件 Decompiler for Java):

1.1 接口定义

c 复制代码
import android.os.IInterface;
import android.os.RemoteException;

public interface IHelloManager extends IInterface {
  public static final String DESCRIPTOR = "android.hardware.hello.IHelloManager";
  
  void hellohal_write(String paramString) throws RemoteException;
  
  String hellohal_read() throws RemoteException;
}

1.2 接口默认空实现

java 复制代码
import android.hardware.hello.IHelloManager;
import android.os.IBinder;
import android.os.RemoteException;

public class Default implements IHelloManager {
  public void hellohal_write(String str) throws RemoteException {}
  
  public String hellohal_read() throws RemoteException {
    return null;
  }
  
  public IBinder asBinder() {
    return null;
  }
}

1.3 服务端 Stub 类的实现

java 复制代码
import android.hardware.hello.IHelloManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;

public abstract class Stub extends Binder implements IHelloManager {
  static final int TRANSACTION_hellohal_write = 1;
  
  static final int TRANSACTION_hellohal_read = 2;
  
  public Stub() {
    attachInterface((IInterface)this, "android.hardware.hello.IHelloManager");
  }
  
  public static IHelloManager asInterface(IBinder obj) {
    if (obj == null)
      return null; 
    IInterface iin = obj.queryLocalInterface("android.hardware.hello.IHelloManager");
    if (iin != null && iin instanceof IHelloManager)
      return (IHelloManager)iin; 
    return (IHelloManager)new Proxy(obj);
  }
  
  public IBinder asBinder() {
    return (IBinder)this;
  }
  
  public static String getDefaultTransactionName(int transactionCode) {
    switch (transactionCode) {
      case 1:
        return "hellohal_write";
      case 2:
        return "hellohal_read";
    } 
    return null;
  }
  
  public String getTransactionName(int transactionCode) {
    this;
    return getDefaultTransactionName(transactionCode);
  }
  
  public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
    String _arg0, _result, descriptor = "android.hardware.hello.IHelloManager";
    if (code >= 1 && code <= 16777215)
      data.enforceInterface(descriptor); 
    switch (code) {
      case 1598968902:
        reply.writeString(descriptor);
        return true;
    } 
    switch (code) {
      case 1:
        _arg0 = data.readString();
        data.enforceNoDataAvail();
        hellohal_write(_arg0);
        reply.writeNoException();
        return true;
      case 2:
        _result = hellohal_read();
        reply.writeNoException();
        reply.writeString(_result);
        return true;
    } 
    return super.onTransact(code, data, reply, flags);
  }
  
  public int getMaxTransactionId() {
    return 1;
  }
}

1.4 代理类 Proxy 的实现

java 复制代码
import android.hardware.hello.IHelloManager;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;

class Proxy implements IHelloManager {
  private IBinder mRemote;
  
  Proxy(IBinder remote) {
    this.mRemote = remote;
  }
  
  public IBinder asBinder() {
    return this.mRemote;
  }
  
  public String getInterfaceDescriptor() {
    return "android.hardware.hello.IHelloManager";
  }
  
  public void hellohal_write(String str) throws RemoteException {
    Parcel _data = Parcel.obtain(asBinder());
    Parcel _reply = Parcel.obtain();
    try {
      _data.writeInterfaceToken("android.hardware.hello.IHelloManager");
      _data.writeString(str);
      boolean _status = this.mRemote.transact(1, _data, _reply, 0);
      _reply.readException();
    } finally {
      _reply.recycle();
      _data.recycle();
    } 
  }
  
  public String hellohal_read() throws RemoteException {
    String _result;
    Parcel _data = Parcel.obtain(asBinder());
    Parcel _reply = Parcel.obtain();
    try {
      _data.writeInterfaceToken("android.hardware.hello.IHelloManager");
      boolean _status = this.mRemote.transact(2, _data, _reply, 0);
      _reply.readException();
      _result = _reply.readString();
    } finally {
      _reply.recycle();
      _data.recycle();
    } 
    return _result;
  }
}

基本就是 java binder 那一套东西,没什么特别要说的


二、硬件服务 Server 端

修改 rameworks/base/services/core/Android.bp,添加 V1 版本依赖

c 复制代码
/frameworks/base/services/core$ git diff .
diff --git a/frameworks/base/services/core/Android.bp b/frameworks/base/services/core/Android.bp
index 1c818c0981..e577457375 100644
--- a/frameworks/base/services/core/Android.bp
+++ b/frameworks/base/services/core/Android.bp
@@ -155,6 +155,8 @@ java_library_static {
         "android.hardware.soundtrigger-V2.3-java",
         "android.hardware.power.stats-V1-java",
         "android.hidl.manager-V1.2-java",
+        "android.hardware.hello-V1-java",

在 frameworks/base/services/core/java/com/android/server 目录下添加:

复制代码
hello/
└──HelloAidlService.java

HelloAidlService.java 的内容如下:

c 复制代码
package com.android.server.hello;

import android.annotation.NonNull;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;

import com.android.server.SystemService;

import android.hardware.hello.IHelloManager;
import android.hardware.hello.IHello;

/**
 * 优化后的Hello AIDL系统服务
 * 核心功能:封装Hello HAL层接口,对外提供Binder服务
 */
public class HelloAidlService extends SystemService {

    // AIDL HAL服务接口实例
    private IHello mVintfHelloHal = null;
    // 对外暴露的系统服务Binder实例
    private IHelloManager mHelloManager = null;

    /**
     * 实现IHelloManager AIDL接口的Binder服务类
     * 核心:转发调用到HAL层接口
     */
    private final class HelloManagerService extends IHelloManager.Stub { 
        
        @Override
        public void hellohal_write(@NonNull String str) throws RemoteException {
            try {
                if (mVintfHelloHal != null) {
                    mVintfHelloHal.hello_write(str);
                }
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        
        @Override
        public String hellohal_read() throws RemoteException {
            try {
                if (mVintfHelloHal != null) {
                    return mVintfHelloHal.hello_read();
                }
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
            return "";
        }
    }

    /**
     * 构造方法:初始化HAL接口,创建Binder服务实例
     * @param context SystemServer上下文
     */
    public HelloAidlService(Context context) {
        super(context);
        
        // 获取HAL层Hello服务的Binder实例
        IBinder binder = Binder.allowBlocking(
                ServiceManager.waitForDeclaredService(IHello.DESCRIPTOR + "/default"));
        if (binder != null) {
            mVintfHelloHal = IHello.Stub.asInterface(binder);
        }

        // 初始化对外暴露的Binder服务
        mHelloManager = new HelloManagerService();
    }

    /**
     * 服务启动:注册Binder服务到ServiceManager
     * 外部可通过Context.getSystemService("hello")获取该服务
     */
    @Override
    public void onStart() {
        // 注意:若Context.HELLO_SERVICE未定义,建议替换为自定义字符串(如"hello")
        publishBinderService("HelloAidl", (IBinder) mHelloManager);
    }

    @Override
    public void onBootPhase(int phase) {
        // 保留空实现,若后续需按启动阶段初始化可在此扩展
    }
}

接着在 SystemServer 中添加启动服务的代码:

java 复制代码
// 不要忘了导包
import com.android.server.hello.HelloAidlService;

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
    // ......
    t.traceBegin("StartHelloAidlHalService");
    mSystemServiceManager.startService(HelloAidlService.class);
    t.traceEnd();
    //......
}

三、硬件服务 Client 端

接着创建客户端:
frameworks/base/core/java/android/hardware/hello/HelloAidlManager.java

java 复制代码
package android.hardware.hello;

import android.annotation.SystemService;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Singleton;
import android.os.ServiceManager;
import android.annotation.Nullable;

/**
 * { @hide }
 */
public final class HelloAidlManager {

    final Context mContext;

    /*
     * @hide
     */
    public HelloAidlManager (Context systemContext) {
        mContext = systemContext;
    }

    /**
     * @hide 只能系统调用
     */
    public static IHelloManager getService(){
        return I_HELLOAIDL_MANAGER_SINGLETON.get();
    }

    @UnsupportedAppUsage
    private static final Singleton<IHelloManager> I_HELLOAIDL_MANAGER_SINGLETON =
            new Singleton<IHelloManager>() {
                @Override
                protected IHelloManager create() {
                    final IBinder b= ServiceManager.getService("HelloAidl");
                    final IHelloManager m = IHelloManager.Stub.asInterface(b);
                    return m;
                }
    };
    
    public void hellohal_write( @Nullable String str){
        try{
            getService().hellohal_write(str);
            return;
        }catch (RemoteException e){
            throw e.rethrowFromSystemServer();
        }
    }

    @Nullable
    public String hellohal_read() {
        try{
            return getService().hellohal_read();
        }catch (RemoteException e){
            throw e.rethrowFromSystemServer();
        }
    }
}

接着修改 frameworks/base/core/java/android/app/SystemServiceRegistry.java

java 复制代码
// 不要忘了 import 包
import android.hardware.hello.HelloAidlManager;

static {
    //......
     registerService("HelloAidlManager", HelloAidlManager.class,
         new CachedServiceFetcher<HelloAidlManager>() {
             @Override
             public HelloAidlManager createService(ContextImpl ctx) {gi
                 return new HelloAidlManager();
             }});
    //......
}

四、App 访问硬件服务

随便找一个本地应用添加以下代码

java 复制代码
import android.hardware.hello.HelloAidlManager;
import android.content.Context;

protected void onCreate(Bundle savedInstanceState) {
    HelloAidlManager manager = (HelloAidlManager) getSystemService("HelloAidlManager");
    manager.hellohal_write("aidl hal successful");
}

五、Selinux 配置

5.1 service_contexts

device/softwinner/ceres/common/sepolicy/vanstone/plat_private/service_contexts

c 复制代码
HelloAidl                 u:object_r:HelloAidl_service:s0

service_contexts 是ServiceManager 服务名到 SELinux 类型的映射表------ 当把服务注册到 ServiceManager(如ServiceManager.addService("HelloAidl", ...))时,SELinux 会根据这行规则,给 "HelloAidl" 这个服务分配对应的安全上下文(标签)。

5.2 service.te

device/softwinner/ceres/common/sepolicy/vanstone/plat_public/service.te

c 复制代码
type HelloAidl_service, service_manager_type, system_server_service;

service.te 是专门定义「ServiceManager 服务类型」的配置文件,这行规则的作用是定义合法的服务类型,并标记其属性,让系统认可这个服务类型。

5.3 system_app.te

device/softwinner/ceres/common/sepolicy/vanstone/non_plat/system_app.te

c 复制代码
allow system_app HelloAidl_service:service_manager find;

system_app.te 是配置「system_app 类型进程(普通系统应用)」权限的文件,这行规则是授权系统应用访问HelloAidl 服务。


六、编译运行

从 Log 来看,成功调用到了 hello 驱动程序

c 复制代码
adb shell
A11:/ # service list | grep hello
1       HelloAidl: [android.hardware.hello.IHelloManager]

HelloAidl服务也成功创建并注册!


相关推荐
诸神黄昏EX2 小时前
Android OTA 之 升级包编译机制
android
2501_915909063 小时前
苹果iOS应用上架详细流程与注意事项解析
android·ios·小程序·https·uni-app·iphone·webview
AC赳赳老秦4 小时前
跨境科技服务的基石:DeepSeek赋能多语言技术文档与合规性说明的深度实践
android·大数据·数据库·人工智能·科技·deepseek·跨境
晚霞的不甘4 小时前
解决 Flutter for OpenHarmony 构建失败:HVigor ERROR 00303168 (SDK component missing)
android·javascript·flutter
2501_944521594 小时前
Flutter for OpenHarmony 微动漫App实战:分享功能实现
android·开发语言·javascript·flutter·ecmascript
kekegdsz4 小时前
Android构建优化:编译速度从 10 分钟编译到 10 秒
android·性能优化·gradle
2501_944521595 小时前
Flutter for OpenHarmony 微动漫App实战:标签筛选功能实现
android·开发语言·前端·javascript·flutter
mjhcsp5 小时前
如何做一个网站?
android
2501_915909065 小时前
在无需越狱的前提下如何对 iOS 设备进行文件管理与数据导出
android·macos·ios·小程序·uni-app·cocoa·iphone