1 Hal层
1.1 新建模块头文件
aosp/hardware/libhardware/include/demo.h
#ifndef ANDROID_DEMO_INTERFACE_H
#define ANDROID_DEMO_INTERFACE_H
#include "hardware.h"
#define DEMO_HARDWARE_MODULE_ID "demo"
struct demo_module_t{
struct hw_module_t common;
};
struct demo_control_device_t{
struct hw_device_t common;
int fd;
const char* (*getName)();
};
struct demo_control_context{
struct demo_control_device_t device;
};
int sum(int a, int b);
#endif //ANDROID_DEMO_INTERFACE_H
其中 DEMO_HARDWARE_MODULE_ID的命名非常重要,它关乎到后面的是否的hw_get_module是否能找到模块。
1.2 新建模块
在 aosp/hardware/libhardware/module中新建demo文件夹,再在文件夹里新建demo.cpp和Android.bp。
aosp/hardware/libhardware/module/demo/demo.cpp
//
// Created by daniel on 23年7月24日.
//
#include <hardware/demo.h>
#include <hardware/hardware.h>
#include <cstdlib>
#include <cutils/log.h>
#include <cstring>
#include <fcntl.h>
int fd;
static const char* getName(){
ALOGI("%s:getName...","Demo_Hal");
return "Demo";
}
static int close(struct hw_device_t* device) {
struct demo_control_device_t* ctx = (struct demo_control_device_t*)device;
if (ctx){
free(ctx);
}
close(fd);
return 0;
};
static int demo_device_open(const hw_module_t* module, const char* name,
hw_device_t** device) {
ALOGI("%s:openning... %s","Demo_Hal", name);
ALOGI("%s:openning... sum(13, 14) = %d","Demo_Hal", sum(13, 14));
struct demo_control_device_t* dev;
dev = (struct demo_control_device_t*)malloc(sizeof (*dev));
memset(dev,0,sizeof(*dev));
dev->common.tag = 100;
dev->common.version = 0;
dev->common.module = const_cast<hw_module_t*>(module);
dev->common.close = close;
dev->getName = getName;
*device = &dev->common;
fd = open("/dev/",O_RDWR);
return 0;
};
static struct hw_module_methods_t demo_module_methods = {
open: demo_device_open
};
struct demo_module_t HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = Demo_HARDWARE_MODULE_ID,
.name = "Default Demo Hal",
.author = "Daniel",
.methods = &demo_module_methods,
}
};
int sum(int a, int b){
a = a+0;
return a+b;
}
aosp/hardware/libhardware/module/demo/Android.bp
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_libhardware_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_libhardware_license"],
}
cc_library_shared {
name: "demo.default",
relative_install_path: "hw",
proprietary: true,
srcs: ["demo.cpp"],
cflags: ["-Wall", "-Werror"],
header_libs: [
"libhardware_headers",
"libutils_headers",
],
shared_libs: ["liblog"],
}
注意demo.default的命名,它跟1.1所说的DEMO_HARDWARE_MODULE_ID相关联,必须**.default。
1.3 编译动态连接库
至此大功告成。编译,执行命令mmm aosp/hardware/libhardware/module/demo/会生成一个demo.default.so在aosp/out/target/product/emulator_x86/system/lib/hw/下,将该so push进手机的system/lib/hw/里,等待后续加载。
2 JNI层
2.1 编写hal获取和jni注册函数
在aosp/frameworks/base/core/jni/下新建文件com_android_server_DemoService.cpp
//
// Created by daniel on 23年7月28日.
//
#define LOG_TAG "DemoServiceJni"
#include <hardware/demo.h>
#include "jni.h"
#include <utils/Log.h>
#include <nativehelper/JNIHelp.h>
#include "core_jni_helpers.h"
using namespace android;
using namespace std;
//extern int sum(int a, int b);
static struct demo_control_device_t* demo_devcie;
static inline int demo_control_open(const struct hw_module_t* module, struct demo_control_device_t** devcie){
return module->methods->open(module, DEMO_HARDWARE_MODULE_ID, (struct hw_device_t**)devcie);
}
static jboolean demo_init(JNIEnv* env , jobject clazz){
demo_module_t* module;
ALOGI("%s:Initialing...",LOG_TAG);
if (hw_get_module(DEMO_HARDWARE_MODULE_ID, (const hw_module_t**)&module) == 0){
ALOGI("%s:Demo Stub found!", LOG_TAG);
if (demo_control_open(&module->common, &demo_devcie) == 0){
ALOGI("%s:Got Stub operator.",LOG_TAG);
return 0;
}
ALOGI("%s failed to open demo device",LOG_TAG);
return -1;
} else{
ALOGI("%s:hw_get_module null %s", LOG_TAG, DEMO_HARDWARE_MODULE_ID);
}
//ALOGI("%s:Initialing... sum(10, 10) = %d",LOG_TAG, sum(10, 10));
return -1;
}
static jstring getName(JNIEnv* env ,jobject clazz){
const char* name = demo_devcie->getName();
return env->NewStringUTF(name);
}
static const JNINativeMethod gMethods[] = {
{"_init","()Z",(void*) demo_init},
{"_getName","()Ljava/lang/String;",(void*) getName}
};
int register_com_android_server_Demo_Service(JNIEnv *env){
ALOGI("%s:Registing...", LOG_TAG);
ALOGI("%s: Methods %s", LOG_TAG, gMethods[0].signature);
ALOGI("%s: Methods %s", LOG_TAG, gMethods[1].signature);
const char *class_name = "com/android/server/DemoService";
jclass clazz = env->FindClass(class_name);
if (clazz == NULL){
ALOGI("%s:class %s had not been founded", LOG_TAG, class_name);
} else{
ALOGI("%s:class %s had been founded", LOG_TAG, class_name);
}
return RegisterMethodsOrDie(env, class_name,
gMethods, NELEM(gMethods));
}
2.2 注册Jni
在aosp/frameworks/base/core/jni/文件夹下找到AndroidRuntime.cpp,然后注册外部函数
extern int register_com_android_server_DemoService(JNIEnv *env);
找到数组变量 static const RegJNIRec gRegJNI[],并增添一元素
REG_JNI(register_com_android_server_DemoService)
至此完成Jni层编写。
3 Framework层编写
3.1 创建Service
新建aosp/frameworks/base/core/java/com/android/server/DemoService.java
package com.android.server;
import com.android.server.IDemoService;
public class DemoService extends IDemoService.Stub{
@Override
public boolean init(){
return _init();
}
@Override
public String getName(){
return _getName();
}
private static native boolean _init();
private static native String _getName();
}
新建aosp/frameworks/base/core/java/com/android/server/IDemoService.java
package com.android.server;
/** @hide */
interface IDemoService {
boolean init();
String getName();
}
3.1 注册Service
在 aosp/frameworks/base/core/java/android/content/Context.java中作如下更改
public abstract class Context {
public static final String DEMO_SERVICE = "demo";
//找到以下变量
@StringDef(suffix = { "_SERVICE" }, value = {
//新增元素
DEMO_SERVICE,
};
}
在aosp/frameworks/base/services/java/com/android/server/SystemServer里添加
public final class SystemServer implements Dumpable {
...
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
...
try {
t.traceBegin("StartDemoService");
Log.i("DemoRunning","addService begining");
DemoService demoService = new DemoService();
ServiceManager.addService("demo", demoService);
demoService.getName());
Log.i("DemoRunning","addService ending");
t.traceEnd();
}catch (Exception e){
e.printStackTrace();
Log.i("DemoRunning","Error " + e.getMessage());
}
...
}
...
}
3.2 配置权限
1 分别在
aosp/system/sepolicy/prebuilts/api/28.0/public/service.st
aosp/system/sepolicy/prebuilts/api/29.0/public/service.st
aosp/system/sepolicy/prebuilts/api/30.0/public/service.st
aosp/system/sepolicy/prebuilts/api/31.0/public/service.st
aosp/system/sepolicy/prebuilts/api/32.0/public/service.st
aosp/system/sepolicy/prebuilts/api/33.0/public/service.st
aosp/system/sepolicy/prebuilts/public/service.st
中添加
ype demo_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
2 分别在
aosp/system/sepolicy/prebuilts/
aosp/system/sepolicy/prebuilts/api/28.0/private/service_contexts
aosp/system/sepolicy/prebuilts/api/29.0/private/service_contexts
aosp/system/sepolicy/prebuilts/api/30.0/private/service_contexts
aosp/system/sepolicy/prebuilts/api/31.0/private/service_contexts
aosp/system/sepolicy/prebuilts/api/32.0/private/service_contexts
aosp/system/sepolicy/prebuilts/api/33.0/public/private/service_contexts
aosp/system/sepolicy/prebuilts/private/service_contexts
中添加
demo u:object_r:demo_service:s0
3 分别在
aosp/system/sepolicy/prebuilts/api/28.0/public/unstrusted_app.te
aosp/system/sepolicy/prebuilts/api/29.0/public/unstrusted_app.te
aosp/system/sepolicy/prebuilts/api/30.0/public/unstrusted_app.te
aosp/system/sepolicy/prebuilts/api/31.0/public/unstrusted_app.te
aosp/system/sepolicy/prebuilts/api/32.0/public/unstrusted_app.te
aosp/system/sepolicy/prebuilts/api/33.0/public/unstrusted_app.te
aosp/system/sepolicy/prebuilts/public/unstrusted_app.te
中添加
allow untrusted_app block_device:blk_file getattr;
4 分别在
aosp/system/sepolicy/prebuilts/
aosp/system/sepolicy/prebuilts/api/28.0/private/unstrusted_app_all.te
aosp/system/sepolicy/prebuilts/api/29.0/private/unstrusted_app_all.te
aosp/system/sepolicy/prebuilts/api/30.0/private/unstrusted_app_all.te
aosp/system/sepolicy/prebuilts/api/31.0/private/unstrusted_app_all.te
aosp/system/sepolicy/prebuilts/api/32.0/private/unstrusted_app_all.te
aosp/system/sepolicy/prebuilts/api/33.0/public/private/unstrusted_app_all.te
aosp/system/sepolicy/prebuilts/private/unstrusted_app_all.te
中添加
allow untrusted_app_all demo_service:service_manager find;
4 编译
执行 mmma aosp/frameworks/base/
make system-image
生成system.img,刷进手机里,重启,然后push 1.3生成的demo.default.so到system/lib/hw/下,再重启。至此完成