目录
- [一、定义 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)
- [5.1 `service_contexts`](#5.1
- 六、编译运行
|--------------|
| 添加硬件访问服务 |

一、定义 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服务也成功创建并注册!