Android增加系统服务访问底层硬件
一、以增加ActionService为例,首先在framework层增加几个文件
1、frameworks/base/services/java/com/android/server/ActionService.java
2、frameworks/base/core/java/android/app/IActionManager.aidl
3、frameworks/base/core/java/android/app/ActionManager.java
4、frameworks/base/services/core/jni/com_android_server_ActionService.cpp
package com.android.server;import android.app.ActionManager;import android.app.IActionManager;public class ActionService extends IActionManager.Stub {private static native boolean init_native();private static native void setIR_native(int val);private static native void setLedColor_native(int val);private static final String TAG = "ActionService"; private Context mContext;private static boolean launcherHasStart = false; public ActionService(Context context) { mContext = context; //Log.e(TAG, "I am handling ACTION_SERVICE init service. added by zs 20180517 for test start to register service"); }@Override public void init(){ init_native(); } @Override public void setIR(int status) { setIR_native(status); }@Override public void setLedColor(int status) { //Log.i(TAG,"---------->>>>yxj add: call setLedColor()"); setLedColor_native(status); }}
/* //device/java/android/android/app/IAlarmManager.aidl**** Copyright 2006, 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.*/package android.app;/*import android.app.PendingIntent;*//** * System private API for talking with the action manager service. * * {@hide} */interface IActionManager {void init();void setIR(int status);void setLedColor(int status);}
package android.app;import android.content.Context;import android.content.Intent;import android.os.RemoteException;import android.os.ServiceManager;import android.app.IActionManager;import android.util.Log;/** * @hide */public class ActionManager { private static IActionManager mService;private Context mContext;private static final String TAG = "ActionManager"; ActionManager(Context context, IActionManager service) { mService = service;mContext = context; } /* function: set IR on/off parm:1 is on, 0 is off */ public void setIR(int status) {try { mService.setIR(status); } catch (RemoteException ex) { } }/* function: set led color parm:1 is blue color, 0 is red */ public void setLedColor(int status) {try {//Log.i(TAG, "--------->>>>yxj add: setLedColor = " + status); mService.setLedColor(status); } catch (RemoteException ex) { } }}
#define LOG_TAG "ActionService"#include "jni.h"#include "JNIHelp.h"#include "android_runtime/AndroidRuntime.h"#include #include #include #include #include namespace android{ struct action_device_t* action_device = NULL;static inline int action_device_open(const hw_module_t* module, struct action_device_t** device) { return module->methods->open(module, ACTION_HARDWARE_MODULE_ID, (struct hw_device_t**)device); } static jboolean action_init(JNIEnv* env, jclass /* clazz */) {action_module_t* module; //ALOGI("------------->>>>yxj add: *action JNI: initializing......"); if(hw_get_module(ACTION_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) { ALOGI("------------->>>>yxj add: action JNI: action Stub found."); if(action_device_open(&(module->common), &action_device) == 0) { ALOGI("------------->>>>yxj add: action JNI: action device is open."); return 1; } ALOGE("------------->>>>yxj add: action JNI: failed to open action device."); return 0; } ALOGE("------------->>>>yxj add: action JNI: failed to get action stub module."); return 0; }static void set_IR(JNIEnv* env, jobject clazz, jint value) { // int val = 0; //masked by zs 20180515 if(!action_device) { ALOGI("------------->>>>yxj add: action JNI: device is not open."); return ; }//ALOGI("------------->>>>yxj add: action JNI: set_IR to device location1."); action_device->setIR(action_device, value); // ALOGI("------------->>>>yxj add: action JNI: set_IR to device. location2"); }static void set_led_color(JNIEnv* env, jobject clazz, jint value) { //ALOGI("------------->>>>yxj add: action JNI: set value %d to device.", value); if(!action_device) { ALOGI("------------->>>>yxj add: action JNI: device is not open."); return; } action_device->setLedColor(action_device, value);} /*JNI 方法表*/ static const JNINativeMethod method_table[] = { {"init_native", "()Z", (void*)action_init}, {"setIR_native", "(I)V", (void*)set_IR}, {"setLedColor_native", "(I)V", (void*)set_led_color}, }; /*注册JNI 方法*/ int register_android_server_ActionService(JNIEnv *env) { return jniRegisterNativeMethods(env, "com/android/server/ActionService", method_table, NELEM(method_table) ); }};
二、注册与添加服务
1、在frameworks/base/services/core/jni/onload.cpp文件中的两个方法中分别添加:
int register_android_server_ActionService(JNIEnv* env);
register_android_server_ActionService(env);
2、在frameworks/base/services/java/com/android/server/SystemServer.java文件中startOtherServices()方法中添加
try {
ServiceManager.addService(Context.ACTION_SERVICE, new ActionService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting action Service", e);
}
3、frameworks/base/services/core/jni/Android.mk文件中增加:
$(LOCAL_REL_DIR)/com_android_server_ActionService.cpp \
4、frameworks/base/core/java/android/content/Context.java文件中增加:
public static final String ACTION_SERVICE = "action";
5、frameworks/base/core/java/android/app/SystemServiceRegistry.java文件增加
registerService(Context.ACTION_SERVICE, ActionManager.class,
new CachedServiceFetcher() {
@Override
public ActionManager createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(Context.ACTION_SERVICE);
IActionManager service = IActionManager.Stub.asInterface(b);
return new ActionManager(ctx.getOuterContext(), service);
}});
6、文件frameworks/base/Android.mk中增加
core/java/android/app/IActionManager.aidl \
7、文件device/rockchip/common/device.mk增加
PRODUCT_PACKAGES += action.default
三、底层相关修改:
1、添加文件hardware/libhardware/include/hardware/action.h
hardware/libhardware/modules/action/action.c
hardware/libhardware/modules/action/Android.mk
#ifndef ANDROID_action_INTERFACE_H#define ANDROID_action_INTERFACE_H#include __BEGIN_DECLS#define ACTION_HARDWARE_MODULE_ID "action"struct action_module_t { struct hw_module_t common;};struct action_device_t { struct hw_device_t common; int fd;int (*setIR)(struct action_device_t* dev, int val);int (*setLedColor)(struct action_device_t* dev, int val);};__END_DECLS#endif
#define LOG_TAG "ActionHAL"#include #include #include #include #include #include #include #include #include #include #define MODULE_NAME "action"#define MODULE_AUTHOR "action"#define DEVICE_NAME "/dev/action_dev"#define SET_AUDIO_SOUCE 1#define SET_FM_FREQ 3#define SET_FM_STATUS 5#define SET_IR 7#define SET_VOLUME 9#define SET_LED_COLOR 11#define SET_IR_BAND 13#define SET_ENABLE_BACKLIGHT 15#define SET_HMDI_RESET 17static int action_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);static int action_device_close(struct hw_device_t* device);static int set_IR(struct action_device_t* dev, int val);static int set_led_color(struct action_device_t* dev, int val);static struct hw_module_methods_t action_module_methods = { open: action_device_open};struct action_module_t HAL_MODULE_INFO_SYM = { common: { tag: HARDWARE_MODULE_TAG, version_major: 1, version_minor: 0, id: ACTION_HARDWARE_MODULE_ID, name: MODULE_NAME, author: MODULE_AUTHOR, methods: &action_module_methods, }};static int action_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device) { struct action_device_t* dev;//ALOGD("------------->>>>yxj add: %s", __FUNCTION__); dev = (struct action_device_t*)malloc(sizeof(struct action_device_t)); if(!dev) { return -EFAULT; } memset(dev, 0, sizeof(struct action_device_t)); dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = 0; dev->common.module = (hw_module_t*)module; dev->common.close = action_device_close;dev->setIR = set_IR;dev->setLedColor = set_led_color;dev->fd = open("/dev/action_dev", O_RDWR);if((dev->fd) < 0){ALOGD("------------->>>>yxj add: open /dev/action_dev fail: error = %s\n", strerror(errno));free(dev); return -EFAULT;}//ALOGD("------------->>>>yxj add: %s, dev->fd = %d", __FUNCTION__, dev->fd); *device = &(dev->common); return 0;}static int action_device_close(struct hw_device_t* device) { struct action_device_t* action_device = (struct action_device_t*)device;if(action_device) { close(action_device->fd); free(action_device); } return 0;}static int set_IR(struct action_device_t* dev, int val) {//ALOGD("------------->>>>yxj add: %s, %d", __FUNCTION__, val);ioctl(dev->fd, SET_IR, val); return 0;}static int set_led_color(struct action_device_t * dev, int val){//ALOGD("------------->>>>yxj add: %s, %d", __FUNCTION__, val);ioctl(dev->fd, SET_LED_COLOR, val);return 0;}
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE_TAGS := optionalLOCAL_PRELINK_MODULE := falseLOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hwLOCAL_SHARED_LIBRARIES := liblog libcutilsLOCAL_SRC_FILES := action.cLOCAL_MODULE := action.defaultinclude $(BUILD_SHARED_LIBRARY)
2、在文件system/core/rootdir/ueventd.rc中增加
/dev/action_dev 0666 system system
3、hardware/libhardware/modules/Android.mk文件hardware_modules中增加
action
4、device/rockchip/common/sepolicy/system_server.te文件增加
allow system_server action_device:chr_file rw_file_perms;
5、device/rockchip/common/sepolicy/service.te增加
type action_service, system_server_service, service_manager_type;
6、device/rockchip/common/sepolicy/service_contexts增加
action u:object_r:action_service:s0
7、device/rockchip/common/sepolicy/file_contexts增加
/dev/action_dev u:object_r:action_device:s0
8、device/rockchip/common/sepolicy/device.te
type action_device, dev_type;
9、增加文件kernel/drivers/char/action/action_dev.c
/* * File: */#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ACTION_DEV_MAJOR_NUM 235#define ACTION_DEV_MINOR_NUM 1#define SET_AUDIO_SOUCE 1#define SET_FM_FREQ 3#define SET_FM_STATUS 5#define SET_IR 7#define SET_VOLUME 9#define SET_LED_COLOR 11#define SET_IR_BAND 13#define SET_ENABLE_BACKLIGHT 15#define SET_HMDI_RESET 17#define DEV_NAME "action_dev"struct led_data{struct delayed_work work;int led_flag;int stop_flash_flag;struct mutex mutex;};static struct class *action_class;static int ir_gpio, ir_gpio1, ir_gpio2, fm_ctl_gpio, hdmi_5v_gpio, led_gpio, detect_hw_version;static int first_set_ir_flag = 0;static struct workqueue_struct *led_workqueue = NULL;static struct led_data *action_led = NULL;extern int sleep_gpio;extern void set_current_source(int source);extern void set_fmkqn800_status(int status);extern void set_fmkqn800_freq(int freq);extern void adjust_volume(int volume);extern bool Check_Adv7181_Singal(void);//extern void Adv7181ModeChange(int val);extern void set_system_boot_finish_to_enable_backlight(int val);static int action_dev_open(struct inode *inode, struct file *file){return 0;}static int action_dev_release(struct inode *inode, struct file *file){return 0;}static int action_dev_read(struct file *file, char __user *buf, size_t count,loff_t *offset){int disc_gpio, ret, detect_hw_version_gpio;disc_gpio = gpio_get_value(hdmi_5v_gpio);if(Check_Adv7181_Singal()==true)disc_gpio = disc_gpio | 0x00000010;detect_hw_version_gpio = gpio_get_value(detect_hw_version);disc_gpio = disc_gpio | (detect_hw_version_gpio << 8);ret = copy_to_user(buf, &disc_gpio, count) ? -EFAULT : ret;;return ret;}static long action_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg){int ret = 0;int parm = (int)arg;switch(cmd){case SET_AUDIO_SOUCE://printk("-------->>>>yxj add: SET_AUDIO_SOUCE, parm = %d\n", parm);set_current_source(parm);break;case SET_FM_STATUS://printk("-------->>>>yxj add: SET_FM_STATUS, parm = %d\n", parm);if(parm == 1){gpio_direction_output(fm_ctl_gpio, 1);msleep(200);set_fmkqn800_status(parm);}else if(parm == 0){ set_fmkqn800_status(parm); gpio_direction_output(fm_ctl_gpio, 0);}else { //Adv7181ModeChange(parm);}/*else if(parm == 3){ // set_fmkqn800_status(parm); Adv7181ModeChange(1);//gpio_direction_output(fm_ctl_gpio, 0);}else if(parm == 4){ // set_fmkqn800_status(parm); Adv7181ModeChange(0);//gpio_direction_output(fm_ctl_gpio, 0);}*/break;case SET_FM_FREQ:set_fmkqn800_freq(parm);break;case SET_IR:if(first_set_ir_flag == 0){gpio_direction_output(ir_gpio, 1);first_set_ir_flag = 1;}if(parm == 1){gpio_direction_output(ir_gpio1, 1);}else{gpio_direction_output(ir_gpio1, 0);}break;case SET_VOLUME:adjust_volume(parm);break;case SET_LED_COLOR:action_led->stop_flash_flag = 1;mutex_lock(&action_led->mutex);if(parm == 1){gpio_direction_output(led_gpio, 0);}else{gpio_direction_output(led_gpio, 1);}mutex_unlock(&action_led->mutex);break;case SET_IR_BAND:if(parm == 1){gpio_direction_output(ir_gpio2, 1); //A band}else{gpio_direction_output(ir_gpio2, 0); //B band}break;case SET_ENABLE_BACKLIGHT:set_system_boot_finish_to_enable_backlight(parm);break;case SET_HMDI_RESET:if(parm == 1){gpio_direction_output(sleep_gpio, 1);}else{gpio_direction_output(sleep_gpio, 0);}break;default:break;}return ret;}struct file_operations action_dev_ops = {.owner= THIS_MODULE,.unlocked_ioctl= action_dev_ioctl,.open= action_dev_open,.read = action_dev_read,.release= action_dev_release,};static struct of_device_id action_dt_match[] = {{ .compatible = "action, action_dev", },};MODULE_DEVICE_TABLE(of, action_dt_match);static void led_work_func(struct work_struct *work){if(action_led->stop_flash_flag == 1)return;mutex_lock(&action_led->mutex);if(action_led->led_flag == 1){gpio_direction_output(led_gpio, 1);action_led->led_flag = 0;}else{gpio_direction_output(led_gpio, 0);action_led->led_flag = 1;}mutex_unlock(&action_led->mutex);queue_delayed_work(led_workqueue, &action_led->work, 300);}static int action_probe(struct platform_device *pdev){int ret;struct device_node *np = (&(pdev->dev))->of_node;action_led = kzalloc(sizeof(*action_led), GFP_KERNEL);if (action_led == NULL) { printk("Alloc GFP_KERNEL memory failed."); return -ENOMEM; }INIT_DELAYED_WORK(&action_led->work, led_work_func);mutex_init(&action_led->mutex);ir_gpio = of_get_named_gpio(np, "ir_gpio", 0);ir_gpio1 = of_get_named_gpio(np, "ir_gpio1", 0);ir_gpio2 = of_get_named_gpio(np, "ir_gpio2", 0);fm_ctl_gpio = of_get_named_gpio(np, "fm_ctl_gpio", 0);hdmi_5v_gpio = of_get_named_gpio(np, "hdmi_5v_gpio", 0);led_gpio = of_get_named_gpio(np, "led_gpio", 0);detect_hw_version = of_get_named_gpio(np, "detect_hw_version", 0);gpio_request(ir_gpio, "ir_gpio");gpio_request(ir_gpio1, "ir_gpio1");gpio_request(ir_gpio2, "ir_gpio2");gpio_request(fm_ctl_gpio, "fm_ctl_gpio");gpio_request(hdmi_5v_gpio, "hdmi_5v_gpio");gpio_request(led_gpio, "led_gpio");gpio_request(detect_hw_version, "detect_hw_version");gpio_direction_output(ir_gpio, 0);gpio_direction_output(ir_gpio2, 1);gpio_direction_input(hdmi_5v_gpio);gpio_direction_input(detect_hw_version);//gpio_direction_output(fm_ctl_gpio, 1);//added by zs for testret = register_chrdev(ACTION_DEV_MAJOR_NUM, DEV_NAME, &action_dev_ops);action_class = class_create(THIS_MODULE, DEV_NAME);device_create(action_class, NULL, MKDEV(ACTION_DEV_MAJOR_NUM, ACTION_DEV_MINOR_NUM), NULL, DEV_NAME);if(ret < 0){printk("---->>>yxj add: [%d]fail to register the character device\n", ret);return ret;}queue_delayed_work(led_workqueue, &action_led->work, 100);return 0;}static int action_remove(struct platform_device *pdev){unregister_chrdev(ACTION_DEV_MAJOR_NUM, DEV_NAME);return 0;}static struct platform_driver action_driver = {.probe= action_probe,.remove= action_remove,.driver = {.name = DEV_NAME,.owner = THIS_MODULE,.of_match_table = action_dt_match,},};int __init action_init(void){int retval;led_workqueue = create_singlethread_workqueue("led_wq");if (!led_workqueue) { printk("Creat workqueue failed."); return -ENOMEM; }retval = platform_driver_register(&action_driver);return retval;}void __exit action_exit(void){cancel_delayed_work(&action_led->work); flush_workqueue(led_workqueue);kfree(action_led);destroy_workqueue(led_workqueue);platform_driver_unregister(&action_driver);}module_init(action_init);module_exit(action_exit);MODULE_AUTHOR("action team");MODULE_DESCRIPTION("ation_dev");MODULE_LICENSE("GPL");
10、kernel/arch/arm/boot/dts/rk3288-evb-android-rk808-lvds.dts中增加
action_dev {
compatible = "action, action_dev";
status = "okay";
ir_gpio = <&gpio7 11 GPIO_ACTIVE_HIGH>;
ir_gpio1 = <&gpio7 13 GPIO_ACTIVE_HIGH>;
ir_gpio2 = <&gpio7 14 GPIO_ACTIVE_HIGH>;
fm_ctl_gpio = <&gpio7 15 GPIO_ACTIVE_HIGH>;
hdmi_5v_gpio = <&gpio5 14 GPIO_ACTIVE_HIGH>;
led_gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
detect_hw_version = <&gpio5 10 GPIO_ACTIVE_HIGH>;
};
11、kernel/.config kernel/.config.old kernel/arch/arm/configs/rockchip_defconfig 增加
CONFIG_ACTION_CHAR_DEV=y
12、kernel/drivers/char/Kconfig增加
source "drivers/char/action/Kconfig"
13、kernel/drivers/char/Makefile增加
obj-$(CONFIG_ACTION_CHAR_DEV) += action/
14、增加文件
## action character device configuration#menu "Action character device"config ACTION_CHAR_DEVbool "ACTION CHAR DEV"default yhelp ACTION CHAR DEV driver.endmenu
15、增加文件
#
# drivers/char/action/Makefile
#
obj-$(CONFIG_ACTION_CHAR_DEV) += action_dev.o
obj-$(CONFIG_FMK9N800) += fmk9n800.o
obj-$(CONFIG_ACTION_CH7107) += ch7107.o
16、kernel/include/config/auto.conf增加
CONFIG_ACTION_CHAR_DEV=y
17、kernel/include/config/auto.conf.cmd增加
drivers/char/action/Kconfig \
18、kernel/include/generated/autoconf.h增加
#define CONFIG_ACTION_CHAR_DEV 1
更多相关文章
- NPM 和webpack 的基础使用
- 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
- 最简单的自定义控件实现
- android源码编译出现No private recovery resources for TARGET_
- 【Android】Android中选项菜单(OptionMenu)的创建
- android 发送短信
- Android_ScrollView
- android studio使用android annotations注解
- android多国语言文件夹