目录
- [一、 添加 aidl 文件](#一、 添加 aidl 文件)
- 二、实现服务端
- [三、JNI 层实现](#三、JNI 层实现)
- 四、客户端实现
- 五、服务端和客户端的注册
-
- [5.1 注册服务端](#5.1 注册服务端)
- [5.2 注册客户端](#5.2 注册客户端)
- [5.3 更新api文件](#5.3 更新api文件)
- [六、Selinux 配置](#六、Selinux 配置)
-
- [6.1 `service_contexts`](#6.1
service_contexts) - [6.2 `service.te`](#6.2
service.te) - [6.3 `platform_app.te`](#6.3
platform_app.te) - [6.4 `untrusted_app.te`](#6.4
untrusted_app.te) - [6.5 `system_server.te`](#6.5
system_server.te)
- [6.1 `service_contexts`](#6.1
- 七、编译运行
|--------------|
| 添加硬件访问服务 |
一、 添加 aidl 文件
添加 aidl 文件 frameworks/base/core/java/android/os/IHelloService.aidl :
c
package android.os;
interface IHelloService
{
void write(String str);
String read();
}
二、实现服务端
添加 frameworks/base/services/core/java/com/android/server/HelloService.java 文件:
c
package com.android.server;
import android.os.IHelloService;
// 硬件服务的服务端实现
public class HelloService extends IHelloService.Stub {
public native void natvieWrite(String str);
public native String nativeRead();
public void write(String str) throws android.os.RemoteException {
natvieWrite(str);
}
public String read() throws android.os.RemoteException {
return nativeRead();
}
}
三、JNI 层实现
添加 frameworks/base/services/core/jni/com_android_server_HelloService.cpp JNI 实现:
c
#define LOG_TAG "HelloService"
#include <jni.h>
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <stdio.h>
#include <string>
#include <nativehelper/JNIHelp.h>
#include <henry/hardware/hello_hidl/1.0/IHello.h> //编译生产文件
#include <hidl/LegacySupport.h>
using android::sp;
using henry::hardware::hello_hidl::V1_0::IHello;
using android::hardware::Return;
using android::hardware::hidl_string;
namespace android
{
static void helloWrite(JNIEnv* env, jobject clazz, jstring str)
{
// 获取服务代理端对象
android::sp<IHello> hw_device = IHello::getService();
if (hw_device == nullptr) {
ALOGD("failed to get hello-hidl");
return;
}
const char* cStr = env->GetStringUTFChars(str, 0);
// 通过代理端对象发起远程调用
hw_device->write(cStr);
}
static jstring helloRead(JNIEnv* env, jobject clazz)
{
jstring res = nullptr;
// 获取服务代理端对象
android::sp<IHello> hw_device = IHello::getService();
if (hw_device == nullptr) {
ALOGD("failed to get hello-hidl");
return res;
}
hw_device->read([&](hidl_string result){
ALOGD("%s\n", result.c_str());
res = env->NewStringUTF(result.c_str());
});
return res;
}
// public native void natvieOpen();
// public native void natvieWrite(String str);
// public native String nativeRead();
static const JNINativeMethod method_table[] = {
{ "natvieWrite", "(Ljava/lang/String;)V", (void*)helloWrite },
{ "nativeRead", "()Ljava/lang/String;", (void*)helloRead }
};
int register_android_server_HelloService(JNIEnv *env)
{
ALOGD("hellotest_jni_register");
return jniRegisterNativeMethods(env, "com/android/server/HelloService",
method_table, NELEM(method_table));
}
};
其中 hardware/hello_hidl/1.0/IHello.h是编译生成文件 编译会报错,需要在frameworks/base/services/core/jni/Android.bp中引入HIDL 接口库"henry.hardware.hello_hidl@1.0"
在frameworks/base/services/core/jni/Android.bp 中添加:
c
git diff base/services/core/jni/Android.bp
diff --git a/frameworks/base/services/core/jni/Android.bp b/frameworks/base/services/core/jni/Android.bp
index b01b2fa5c2..f9d0f7e6bf 100644
--- a/frameworks/base/services/core/jni/Android.bp
+++ b/frameworks/base/services/core/jni/Android.bp
@@ -36,6 +36,7 @@ cc_library_static {
"gnss/Utils.cpp",
"stats/SurfaceFlingerPuller.cpp",
"com_android_server_adb_AdbDebuggingManager.cpp",
+ "com_android_server_HelloService.cpp",
"com_android_server_ActivityManagerService.cpp",
"com_android_server_am_BatteryStatsService.cpp",
"com_android_server_biometrics_SurfaceToNativeHandleConverter.cpp",
@@ -176,6 +177,7 @@ cc_defaults {
"android.hardware.vibrator@1.2",
"android.hardware.vibrator@1.3",
"android.hardware.vr@1.0",
+ "henry.hardware.hello_hidl@1.0",
"android.hidl.token@1.0-utils",
"android.frameworks.schedulerservice@1.0",
"android.frameworks.sensorservice@1.0",
在 frameworks/base/services/core/jni/onload.cpp 中添加:
c
git diff frameworks/base/services/core/jni/onload.cpp
diff --git a/frameworks/base/services/core/jni/onload.cpp b/frameworks/base/services/core/jni/onload.cpp
index b50472d7b9..7ce091a509 100644
--- a/frameworks/base/services/core/jni/onload.cpp
+++ b/frameworks/base/services/core/jni/onload.cpp
@@ -64,6 +64,7 @@ int register_android_server_FaceService(JNIEnv* env);
int register_android_server_GpuService(JNIEnv* env);
int register_android_server_stats_pull_StatsPullAtomService(JNIEnv* env);
int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env);
+int register_android_server_HelloService(JNIEnv* env);
};
using namespace android;
@@ -121,5 +122,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_GpuService(env);
register_android_server_stats_pull_StatsPullAtomService(env);
register_android_server_sensor_SensorService(vm, env);
+ register_android_server_HelloService(env);
return JNI_VERSION_1_4;
}
四、客户端实现
添加一个接口 frameworks/base/core/java/android/os/Hello.java:
java
package android.os;
import android.annotation.Nullable; // 导入空指针注解
import android.annotation.NonNull;
import android.annotation.SuppressLint; // 导入Lint抑制注解
@SuppressLint("RethrowRemoteException")
public abstract class Hello {
public Hello() {
}
public abstract int write(@NonNull String st);
@Nullable
public abstract String read();
}
实现接口 frameworks/base/core/java/android/os/HelloManager.java:
c
package android.os;
import android.annotation.NonNull; // 导入非空注解
import android.annotation.Nullable; // 导入可空注解
import android.annotation.SuppressLint; // 导入Lint抑制注解
import android.content.Context;
import android.os.ServiceManager; // 补全ServiceManager导入(原代码漏了)
import android.os.RemoteException; // 导入RemoteException用于捕获
import android.os.ServiceSpecificException; // 新增:系统推荐的RuntimeException子类
import android.util.Log;
/**
* Vibrator implementation that controls the main system vibrator.
*
* @hide
*/
// 抑制RethrowRemoteException(核心,解决异常声明问题)
@SuppressLint("RethrowRemoteException")
public class HelloManager extends Hello {
private static final String TAG = "HelloManager";
private final IHelloService mService;
// 获取Hello服务的代理端
public HelloManager() {
mService = IHelloService.Stub.asInterface(
ServiceManager.getService("HelloService"));
}
@Override
public int write(@NonNull String str) {
if (str == null) {
Log.e(TAG, "write str is null");
throw new IllegalArgumentException("str must not be null");
}
if (mService != null) {
try {
mService.write(str);
return 0; // 调用成功返回0
} catch (RemoteException e) {
Log.e(TAG, "write failed: ", e);
throw new ServiceSpecificException(1002, "write remote service failed: " + e.getMessage());
}
}
Log.w(TAG, "mService is null, write failed");
return -1; // 服务为空返回-1
}
@Nullable
@Override
public String read() {
if (mService != null) {
try {
return mService.read(); // 调用成功返回读取结果
} catch (RemoteException e) {
Log.e(TAG, "read failed: ", e);
throw new ServiceSpecificException(1003, "read remote service failed: " + e.getMessage());
}
}
Log.w(TAG, "mService is null, read return null");
return null; // 服务为空返回null
}
}
五、服务端和客户端的注册
最最最重要的莫过于这里服务端和客户端的注册了
在 frameworks/base/core/java/android/content/Context.java 中添加:
c
git diff frameworks/base/core/java/android/content/Context.java
diff --git a/frameworks/base/core/java/android/content/Context.java b/frameworks/base/core/java/android/content/Context.java
index 3dc3d78153..4d0c92299c 100644
--- a/frameworks/base/core/java/android/content/Context.java
+++ b/frameworks/base/core/java/android/content/Context.java
@@ -3600,6 +3600,7 @@ public abstract class Context {
/** @hide */
@StringDef(suffix = { "_SERVICE" }, value = {
+ HELLO_SERVICE,
POWER_SERVICE,
//@hide: POWER_STATS_SERVICE,
WINDOW_SERVICE,
@@ -3961,6 +3962,8 @@ public abstract class Context {
*/
public static final String POWER_SERVICE = "power";
+ public static final String HELLO_SERVICE = "hello";
+
/**
* Use with {@link #getSystemService(String)} to retrieve a
* {@link android.os.PowerStatsService} for accessing power stats
5.1 注册服务端
修改 frameworks/base/services/java/com/android/server/SystemServer.java:
c
git diff frameworks/base/services/java/com/android/server/SystemServer.java
diff --git a/frameworks/base/services/java/com/android/server/SystemServer.java b/frameworks/base/services/java/com/android/server/SystemServer.java
index 16c9475658..f104d7185b 100644
--- a/frameworks/base/services/java/com/android/server/SystemServer.java
+++ b/frameworks/base/services/java/com/android/server/SystemServer.java
@@ -1457,6 +1457,10 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(KeyChainSystemService.class);
t.traceEnd();
+ t.traceBegin("StartHelloService");
+ ServiceManager.addService("HelloService", new HelloService());
+ t.traceEnd();
+
t.traceBegin("StartSchedulingPolicyService");
ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
t.traceEnd()
5.2 注册客户端
c
git diff frameworks/base/core/java/android/app/SystemServiceRegistry.java
diff --git a/frameworks/base/core/java/android/app/SystemServiceRegistry.java b/frameworks/base/core/java/android/app/SystemServiceRegistry.java
index 32ea41b2c7..5e2d6b0b57 100644
--- a/frameworks/base/core/java/android/app/SystemServiceRegistry.java
+++ b/frameworks/base/core/java/android/app/SystemServiceRegistry.java
@@ -147,6 +147,8 @@ import android.net.vcn.VcnManager;
import android.net.wifi.WifiFrameworkInitializer;
import android.net.wifi.nl80211.WifiNl80211Manager;
import android.nfc.NfcManager;
+import android.os.Hello;
+import android.os.HelloManager;
import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.BatteryStatsManager;
@@ -290,6 +292,13 @@ public final class SystemServiceRegistry {
return new AccountManager(ctx, service);
}});
+ registerService(Context.HELLO_SERVICE, Hello.class,
+ new CachedServiceFetcher<Hello>() {
+ @Override
+ public Hello createService(ContextImpl ctx) {
+ return new HelloManager();
+ }});
+
registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
new CachedServiceFetcher<ActivityManager>() {
@Override
5.3 更新api文件
c
git diff frameworks/base/core/api/current.txt
diff --git a/frameworks/base/core/api/current.txt b/frameworks/base/core/api/current.txt
index 624ded0577..cf65840113 100644
--- a/frameworks/base/core/api/current.txt
+++ b/frameworks/base/core/api/current.txt
@@ -10644,6 +10644,7 @@ package android.content {
field public static final String FINGERPRINT_SERVICE = "fingerprint";
field public static final String GAME_SERVICE = "game";
field public static final String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
+ field public static final String HELLO_SERVICE = "hello";
field public static final String INPUT_METHOD_SERVICE = "input_method";
field public static final String INPUT_SERVICE = "input";
field public static final String IPSEC_SERVICE = "ipsec";
@@ -31288,6 +31289,12 @@ package android.os {
field public static final float UNDEFINED_TEMPERATURE = -3.4028235E38f;
}
+ public abstract class Hello {
+ ctor public Hello();
+ method @Nullable public abstract String read();
+ method public abstract int write(@NonNull String);
+ }
+
public interface IBinder {
六、Selinux 配置
在自己的项目下更改或添加如下规则
6.1 service_contexts
c
HelloService u:object_r:HelloServiceType:s0
| 规则语句 | 含义作用 |
|---|---|
| HelloService u:object_r:HelloServiceType:s0 | 系统服务名称「HelloService」与 SELinux 安全上下文「u:object_r:HelloServiceType:s0」做绑定映射;安全上下文格式固定为 用户:角色:SELinux类型:安全级别,核心有效内容为HelloServiceType |
6.2 service.te
c
type HelloServiceType, app_api_service, system_server_service, service_manager_type;
| 规则语句 | 含义作用 |
|---|---|
| type HelloServiceType, app_api_service, system_server_service, service_manager_type; | 显式定义一个全新的 SELinux 自定义类型「HelloServiceType」,并为该类型绑定 3 个系统预置的核心属性标签,多个属性用逗号分隔 |
6.3 platform_app.te
c
allow platform_app HelloServiceType:service_manager find;
| 规则语句 | 含义作用 |
|---|---|
| allow platform_app HelloServiceType:service_manager find; | 遵循 SELinux 核心语法:允许「主体类型 - platform_app」对「客体类型 - HelloServiceType」的「资源类别 - service_manager(系统服务管理器)」执行「find(查找)」这一个权限 |
6.4 untrusted_app.te
c
allow untrusted_app HelloServiceType:service_manager find;
| 规则语句 | 含义作用 |
|---|---|
| allow untrusted_app HelloServiceType:service_manager find; | 遵循 SELinux 核心语法:允许「主体类型 - untrusted_app」对「客体类型 - HelloServiceType」的「资源类别 - service_manager」执行「find(查找)」权限 |
6.5 system_server.te
c
allow system_server HelloServiceType:service_manager { add find };
allow system_server hello_hidl_hwservice:hwservice_manager { find };
allow system_server hello_hidl:binder { call };
| 规则语句 | 含义作用 |
|---|---|
| allow system_server HelloServiceType:service_manager { add find }; | 遵循 SELinux 核心语法:允许「主体类型 - system_server」对「客体类型 - HelloServiceType」的「资源类别 - service_manager」执行「add(注册)+find(查找)」两个权限 |
| allow system_server hello_hidl_hwservice:hwservice_manager { find }; | 遵循 SELinux 核心语法:允许「主体类型 - system_server」对「客体类型 - hello_hidl_hwservice」的「资源类别 - hwservice_manager(HIDL 服务管理器)」执行「find(查找)」权限 |
| allow system_server hello_hidl:binder { call }; | 遵循 SELinux 核心语法:允许「主体类型 - system_server」对「客体类型 - hello_hidl」的「资源类别 - binder(安卓跨进程通信核心)」执行「call(远程调用)」权限 |
七、编译运行
c
source build/envsetup.sh
lunch xxx
make -j32