Android11(RK3568)自定义服务制作(3)-Hardware制作和权限管理
根據上一篇Android11(RK3568)自定義服務制作(2)-Service制作?完成了系統service的注冊后,進一步就要完成Hardware層的制作,完成自定義service跟kernel驅動的調用。
通過Service調用Kernel驅動的最簡單方法就是用JNI。
首先在hardware/libhardware/modules/下創建hello文件夾,并在hello文件夾中添加hello.c文件
#define LOG_TAG "HelloStub"#include <hardware/hardware.h> #include <hardware/hello.h> // #include <fcntl.h> #include <errno.h> #include <cutils/log.h> #include <cutils/atomic.h>#include <malloc.h> #include <stdint.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h>#define DEVICE_NAME "/dev/hello" #define MODULE_NAME "Hello" #define MODULE_AUTHOR "sommer_jiang@163.com"/*設備打開和關閉接口*/ static int hello_device_open(const struct hw_module_t *module, const char *name, struct hw_device_t **device); static int hello_device_close(struct hw_device_t *device);/*設備訪問接口*/ static int hello_set_val(struct hello_device_t *dev, int val); static int hello_get_val(struct hello_device_t *dev, int *val);static int hello_device_open(const struct hw_module_t *module, const char *name, struct hw_device_t **device) {struct hello_device_t *dev;dev = (struct hello_device_t *)malloc(sizeof(struct hello_device_t));if (!dev){ALOGE("Hello Stub: failed to alloc space");return -EFAULT;}memset(dev, 0, sizeof(struct hello_device_t));dev->common.tag = HARDWARE_DEVICE_TAG;dev->common.version = 0;dev->common.module = (hw_module_t *)module;dev->common.close = hello_device_close;dev->set_val = hello_set_val;dev->get_val = hello_get_val;if ((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1){ALOGE("Hello Stub: failed to open /dev/hello -- %s.", strerror(errno));free(dev);return -EFAULT;}*device = &(dev->common);ALOGI("Hello Stub: open /dev/hello successfully.");ALOGI("Hello Stub: name -- %s.", name);return 0; }static int hello_device_close(struct hw_device_t *device) {struct hello_device_t *hello_device = (struct hello_device_t *)device;if (hello_device){close(hello_device->fd);free(hello_device);}return 0; }static int hello_set_val(struct hello_device_t *dev, int val) {ALOGI("Hello Stub: set value %d to device.", val);write(dev->fd, &val, sizeof(val));return 0; }static int hello_get_val(struct hello_device_t *dev, int *val) {if (!val){ALOGE("Hello Stub: error val pointer");return -EFAULT;}read(dev->fd, val, sizeof(*val));ALOGI("Hello Stub: get value %d from device", *val);return 0; }/*模塊方法表*/ static struct hw_module_methods_t hello_module_methods = {.open = hello_device_open};/*模塊實例變量*/ struct hello_module_t HAL_MODULE_INFO_SYM = {.common = {.tag = HARDWARE_MODULE_TAG,.version_major = 1,.version_minor = 0,.id = HELLO_HARDWARE_MODULE_ID,.name = MODULE_NAME,.author = MODULE_AUTHOR,.methods = &hello_module_methods,}};并在相同的目錄寫下Android.bp,內容如下:
// Copyright (C) 2013 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License.cc_library_shared {name: "hello.default",relative_install_path: "hw",proprietary: true,srcs: ["hello.c"],cflags: ["-Wall", "-Werror"],header_libs: ["libhardware_headers"],shared_libs: ["liblog"], }接下來在hardware/libhardware/include/hardware/中添加供引用的hello.h文件
#ifndef ANDROID_HELLO_INTERFACE_H #define ANDROID_HELLO_INTERFACE_H #include <hardware/hardware.h> __BEGIN_DECLS /*定義模塊ID*/ #define HELLO_HARDWARE_MODULE_ID "hello" /*硬件模塊結構體*/ struct hello_module_t { struct hw_module_t common; }; /*硬件接口結構體*/ struct hello_device_t { struct hw_device_t common; int fd; int (*set_val)(struct hello_device_t* dev, int val); int (*get_val)(struct hello_device_t* dev, int* val); }; __END_DECLS #endif這幾個完成后別忘了在/hardware/libhardware/Android.mk中添加以下硬件模塊
hardware_modules := \hello添加完這些后,可以采用mmm編譯整個libhardware來把硬件驅動層完成。
完成了硬件驅動層后,最艱難痛苦的一步來了,就是selinux的填寫。其實按照規律也不是很難填寫。
/device/rockchip/common/sepolicy/vendor/device.te添加以下設備
#sommerjiang 20211101 add type hello_device, dev_type;/device/rockchip/common/sepolicy/vendor/domain.te添加以下代碼
#sommerjiang 20211101 add allow domain hello_device:chr_file rw_file_perms;/device/rockchip/common/sepolicy/vendor/file_contexts添加以下代碼
//sommer.jiang,20211115,add for /dev/hello /dev/hello u:object_r:hello_device:s0/device/rockchip/common/sepolicy/private/service_contexts添加以下代碼
hello u:object_r:hello_service:s0/device/rockchip/common/sepolicy/vendor/service.te添加以下代碼
type hello_service, system_api_service, system_server_service, service_manager_type;/device/rockchip/common/sepolicy/vendor/system_app.te添加以下代碼
#sommerjiang 20211101 add allow system_app hello_service:service_manager find;/device/rockchip/common/sepolicy/vendor/system_server.te添加以下代碼
#sommerjiang 20211101 add allow system_server hello_device:chr_file rw_file_perms; allow system_server hello_service:service_manager {add };device/rockchip/common/sepolicy/vendor/untrusted_app.te添加以下代碼
#sommer.jiang add allow untrusted_app hello_service:service_manager find;至此,所有的中間層都完成了。
總結
以上是生活随笔為你收集整理的Android11(RK3568)自定义服务制作(3)-Hardware制作和权限管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络编程--群聊
- 下一篇: jade选峰之后怎么去掉_jade使用教