目录
- [一、添加 aidl 文件](#一、添加 aidl 文件)
- 二、服务端实现
- [三、JNI 层实现](#三、JNI 层实现)
- 四、客户端实现
- 五、服务端和客户端的注册
-
- [5.1 注册服务端](#5.1 注册服务端)
- [5.2 注册客户端](#5.2 注册客户端)
- [5.3 更新api文件](#5.3 更新api文件)
- [六、Selinux 配置](#六、Selinux 配置)
|--------------|
| 添加硬件访问服务 |
一、添加 aidl 文件
添加 aidl 文件 frameworks/base/core/java/android/os/IHelloService.aidl :
java
package android.os;
/**
* @hide
*/
interface IHelloService {
void open();
void write(String str);
String read();
}
二、服务端实现
添加 frameworks/base/services/core/java/com/android/server/HelloService.java 文件:
java
package com.android.server;
import android.os.IHelloService;
// 硬件服务的服务端实现
public class HelloService extends IHelloService.Stub {
public native void natvieOpen();
public native void natvieWrite(String str);
public native String nativeRead();
public void open() throws android.os.RemoteException {
natvieOpen();
}
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 <nativehelper/JNIHelp.h>
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware/hello_hal.h>
#include <stdio.h>
#include <string>
namespace android
{
static hw_module_t *gHelloModule = NULL;
static hello_hal_device_t *gHelloHalDevice = NULL;
static void helloOpen(JNIEnv env, jobject clazz)
{
ALOGD("Hello_test_jni_open");
if (gHelloModule != NULL) {
return;
}
int err = hw_get_module(HELLO_HAL_HARDWARE_MODULE_ID, (hw_module_t const**)&gHelloModule);
if (err) {
ALOGE("Couldn't load %s module (%s)", HELLO_HAL_HARDWARE_MODULE_ID, strerror(-err));
} else {
if (gHelloModule) {
ALOGD("Hello_test_jni_open get module sucess");
hello_hal_methods_open(gHelloModule, &gHelloHalDevice);
}
}
if(gHelloHalDevice) {
gHelloHalDevice->hello_hal_open(gHelloHalDevice);
}
}
static void helloWrite(JNIEnv* env, jobject clazz, jstring str)
{
if (gHelloHalDevice) {
ALOGD("Hello_test_jni_write");
const char * c_str = NULL;
jboolean isCopy;
c_str = env->GetStringUTFChars(str, &isCopy); //从jstring指针中获取数据
ALOGD("Hello_test_jni_write %s",c_str);
gHelloHalDevice->hello_hal_write(gHelloHalDevice, c_str);
}
else {
ALOGW("Tried to hello but there is no hello device.");
}
}
static jstring helloRead(JNIEnv* env, jobject clazz) {
if (gHelloHalDevice) {
ALOGD("Hello_test_jni_read");
char* data = (char*)malloc(1024);
if (data == NULL) {
ALOGE("helloRead: malloc data failed");
return env->NewStringUTF("malloc fail");
}
memset(data, 0, 1024);
int ret = gHelloHalDevice->hello_hal_read(gHelloHalDevice, data);
ALOGD("Hello_test_jni_read result is %s, ret=%d", data, ret);
if (ret > 0 && data[0] != '\0') {
size_t str_len = strnlen(data, ret);
if (str_len == (size_t)ret) {
if (ret < 1023) { // 留空间
data[ret] = '\0';
str_len = ret;
} else {
data[1023] = '\0'; // 截断
str_len = 1023;
}
}
jbyteArray array = env->NewByteArray(str_len);
env->SetByteArrayRegion(array, 0, str_len, (const jbyte *)data);
jstring strEncode = env->NewStringUTF("UTF-8");
jclass cls = env->FindClass("java/lang/String");
jmethodID ctor = env->GetMethodID(cls, "<init>", "([BLjava/lang/String;)V");
jstring retStr = (jstring) env->NewObject(cls, ctor, array, strEncode);
// 释放
free(data);
env->DeleteLocalRef(array);
env->DeleteLocalRef(strEncode);
env->DeleteLocalRef(cls);
return retStr;
} else {
free(data);
return env->NewStringUTF("no msg");
}
}
return env->NewStringUTF("no msg");
}
// public native void natvieOpen();
// public native void natvieWrite(String str);
// public native String nativeRead();
static const JNINativeMethod method_table[] = {
{ "natvieOpen", "()V", (void*)helloOpen },
{ "natvieWrite", "(Ljava/lang/String;)V", (void*)helloWrite },
{ "nativeRead", "()Ljava/lang/String;", (void*)helloRead }
};
int register_android_server_HelloService(JNIEnv *env)
{
ALOGD("Hello_test_jni_register");
return jniRegisterNativeMethods(env, "com/android/server/HelloService",
method_table, NELEM(method_table));
}
};
在frameworks/base/services/core/jni/Android.bp 中添加:
c
xuejie@vt-PowerEdge-R740:~/A11a133a12$ git diff frameworks/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..6884e332e4 100644
--- a/frameworks/base/services/core/jni/Android.bp
+++ b/frameworks/base/services/core/jni/Android.bp
@@ -72,6 +72,7 @@ cc_library_static {
"com_android_server_am_LowMemDetector.cpp",
"com_android_server_pm_PackageManagerShellCommandDataLoader.cpp",
"com_android_server_sensor_SensorService.cpp",
+ "com_android_server_HelloService.cpp",
"onload.cpp",
":lib_cachedAppOptimizer_native",
":lib_networkStatsFactory_native",
在 frameworks/base/services/core/jni/onload.cpp 中添加:
c
xuejie@vt-PowerEdge-R740:~/A11a133a12$ 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;
// 在这里注册 JNI 函数
// java 层的 native 方法就能调用到对应的 native 层函数了
@@ -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 open();
public abstract int write(@NonNull String st);
@Nullable
public abstract String read();
}
实现接口 frameworks/base/core/java/android/os/HelloManager.java:
java
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 open() {
if (mService != null) {
try {
mService.open();
return 0; // 调用成功返回0
} catch (RemoteException e) {
Log.e(TAG, "open failed: ", e);
throw new ServiceSpecificException(1001, "open remote service failed: " + e.getMessage());
}
}
Log.w(TAG, "mService is null, open failed");
return -1; // 服务为空返回-1
}
@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 中添加:
java
xuejie@vt-PowerEdge-R740:~/A11a133a12$ 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:
java
xuejie@vt-PowerEdge-R740:~/A11a133a12$ 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..ce7e147950 100644
--- a/frameworks/base/services/java/com/android/server/SystemServer.java
+++ b/frameworks/base/services/java/com/android/server/SystemServer.java
@@ -1457,6 +1457,11 @@ 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 注册客户端
java
xuejie@vt-PowerEdge-R740:~/A11a133a12$ 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..4603e03935 100644
--- a/frameworks/base/core/java/android/app/SystemServiceRegistry.java
+++ b/frameworks/base/core/java/android/app/SystemServiceRegistry.java
@@ -184,6 +184,8 @@ import android.os.image.IDynamicSystemService;
import android.os.incremental.IIncrementalService;
import android.os.incremental.IncrementalManager;
import android.os.storage.StorageManager;
+import android.os.Hello;
+import android.os.HelloManager;
import android.permission.LegacyPermissionManager;
import android.permission.PermissionCheckerManager;
import android.permission.PermissionControllerManager;
@@ -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
xuejie@vt-PowerEdge-R740:~/A11a133a12$ 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..df3a5edaa6 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,13 @@ package android.os {
field public static final float UNDEFINED_TEMPERATURE = -3.4028235E38f;
}
+ public abstract class Hello {
+ ctor public Hello();
+ method public abstract int open();
+ method @Nullable public abstract String read();
+ method public abstract int write(@NonNull String);
+ }
+
public interface IBinder {
六、Selinux 配置
修改 system/sepolicy/service.te:
c
type HelloServiceType, app_api_service, system_server_service, service_manager_type;
修改 system/sepolicy/service_contexts:
c
HelloService u:object_r:HelloServiceType:s0
修改 system/sepolicy/platform_app.te,让系统 App 可以访问我们自定义的 Binder 服务:
c
allow platform_app HelloServiceType:service_manager find;
修改 system/sepolicy/untrusted_app.te,让普通 App 可以访问我们自定义的 Binder 服务:
c
allow untrusted_app HelloServiceType:service_manager find;
最后,让 SystemServer 可以访问到 hello 驱动,修改 system/sepolicy/system_server.te:
c
allow system_server hello_dev_t:chr_file { open read write };