实现相应的JNI部分已经sever部分
此次实现主要涉及的修改两个目录的文件 hardware,以及framework。
一、修改hardware目录:
由于平台原因,使用的主要是hardware\libhardware_legacy 目录下的文件,接口为老的接口,不同于老罗使用的相关,自己写代码可以参考vibrator 马达的实现。
添加头文件hardware\libhardware_legacy\include\hardware_legacy\welcome.h
#ifndef _ANDROID_WELCOME_INTERFACE_H_
#define _ANDROID_WELCOME_INTERFACE_H_
#if 1
#if __cplusplus
extern "C" {
#endif
// 定义模块ID
//#define WELCOME_HARDWARE_MODULE_ID "welcome"
//硬件接口结构体
int set_val(const char *sysfs_path,int val);
int get_val(const char *sysfs_path,int* val);
#if __cplusplus
} // extern "C"
#endif
#endif
#endif //__ANDROID_WELCOME_INTERFACE_H__
2、添加相应的实现文件\hardware\libhardware_legacy
2.1 在此目录先新建welcome 目录用于统一管理本次hal层代码,并添加相关Android.mk 文件添加编译规则
LOCAL_SRC_FILES += welcome/welcome.c
2.2 添加实现文件welcome.c
#define LOG_TAG "welcomeStub"
#include <hardware/hardware.h>
#include <hardware_legacy/welcome.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <cutils/log.h>
#include <cutils/atomic.h>
#define DEVICE_NAME "/dev/welcomf"
#define MODULE_AUTHOR "atlas_li@126.com"
//设备访问接口
int welcome_set_val(char *sysfs_path,int val);
int welcome_get_val(char *sysfs_path,int* val);
//设备打开和关闭接口
int welcome_device_open(const struct hw_module_t* module,const char* name, struct hw_device_t** device){
return 0;
}
int welcome_device_close(struct hw_device_t* device){
return 0;
}
//设备访问接口
int set_val(const char *sysfs_path,int val){
int fd;
if((fd = open(DEVICE_NAME,O_RDWR)) == -1){
ALOGE("Welcome Staub : failed to open %s .%m",DEVICE_NAME);
return -EFAULT;
}
ALOGI("Welcome Stub: set value %d to device.",val);
write(fd,&val,sizeof(val));
close(fd);
return 0;
}
int get_val(const char *sysfs_path,int* val){
int fd;
if((fd = open(DEVICE_NAME,O_RDWR)) == -1){
ALOGE("Welcome Staub : failed to open %s .%m",DEVICE_NAME);
return -EFAULT;
}
if(!val){
ALOGE("Welcome Stube: error val pointer");
return -EFAULT;
}
read(fd,val,sizeof(*val));
ALOGI("Welcome Stub: get value %d from device",*val);
close(fd);
return 0;
}
此部分耗时比较常,按老罗的方式,添加会导致手机不能正常开机一直停留在开机动画过程,故借鉴此平台的马达实现部分对代码进行修改。
2.3 将相应的代码合入到对应的库文件中修改hardware\libhardware_legacy\Android.mk 添加对应模块welcome
legacy_modules := power uevent vibrator wifi qemu qemu_tracing welcome
二、修改framework部分
此部分主要包含以下几个部分的实现:实现相应的JNI文件,实现相应的aidl文件,实现相关的server文件,配置相关文件让jni与server正常工作
1、实现相应的JNI文件: frameworks\base\services\core\jni
1.1、使用相应的jni文件:com_android_server_WelcomeService.cpp
/*
* Copyright (C) 2009 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.
*/
#if 1
#define LOG_TAG "WelcomeService"
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware_legacy/welcome.h>
#include <stdio.h>
namespace android
{
const char* DEVICE_PATH ="/dev/welcomf" ;
// 通过硬件抽象层定义的硬件访问接口设置硬件寄存器val的值
static void welcome_setVal(JNIEnv *env, jobject clazz,jint value){
int val = value;
ALOGI("Welcome JNI: set value %d to device.",val);
set_val(DEVICE_PATH,val);
}
//通过硬件抽象定义的硬件访问接口读取硬件寄存器val 值
static jint welcome_getVal(JNIEnv *env, jobject clazz){
int val = 0;
get_val(DEVICE_PATH,&val);
ALOGI("Welcome JNI: get value %d from device.",val);
return val;
}
//通过硬件抽象层定义的硬件模块打开接口打开硬件设备 vib 在hardware h文件中
/*static inline int welcome_device_open(const hw_module_t* module,struct welcome_device_t** device){
return module->methods->open(module,WELCOME_HARDWARE_MODULE_ID,(struct hw_device_t**)device);
}*/
//通过硬件模块ID 来加载指定的在硬件模块并打开硬件
static jboolean welcome_init(JNIEnv *env, jobject clazz){
ALOGI("Welcome JNI :initializing...... ");
return 0;
}
//JNI 方法表
static JNINativeMethod method_table[] = {
// {"init_native","()Z",(void *)welcome_init},
{"setVal_native","(I)V",(void *)welcome_setVal},
{"getVal_native","()I",(void *)welcome_getVal},
};
//JNI 注册
int register_android_server_WelcomeService(JNIEnv *env){
return jniRegisterNativeMethods(env,"com/android/server/WelcomeService",method_table,NELEM(method_table));
}
};//namespace android
#endif
1.2、修改编译规则,让jni参与编译,已经调用
1.2.1、修改该目录下的Android.mk 文件 在LOCAL_SRC_FILES += \ 增加一行
LOCAL_SRC_FILES += \
.................
$(LOCAL_REL_DIR)/com_android_server_WelcomeService.cpp \
1.2.2、添加相关调用,修改同目录下的:onload.cpp
首先在namespace android增加register_android_server_WelcomeService函数声明:
namespace android {
..............................................................................................
int register_android_server_WelcomeService(JNIEnv *env);
在JNI_onLoad增加register_android_server_HelloService函数调用:
extern "C" jint JNI_onLoad(JavaVM* vm, void* reserved){
.................................................................................................
register_android_server_WelcomeService(env);
2、实现相应的aidl文件
.1、frameworks\base\core\java\android\os\IWelcomeService.aidl
/**
* Copyright (c) 2007, 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.os;
/** {@hide} */
interface IWelcomeService
{
void setVal(int val);
int getVal();
}
2.2、添加入编译规则 frameworks\base\Android.mk
LOCAL_SRC_FILES += \
..........
core/java/android/os/IWelcomeService.aidl \
3、实现相关的server文件
3.1、实现相应的server文件:frameworks\base\services\core\java\com\android\server\WelcomeService.java
/*
* Copyright (C) 2008 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 com.android.server;
//import android.app.AppOpsManager;
//import android.content.BroadcastReceiver;
import android.content.Context;
import android.os.IWelcomeService;
import com.android.server.SystemService;
import android.app.Service;
import android.util.Slog;
public class WelcomeService extends IWelcomeService.Stub{
private static final String TAG = "WelcomeService";
WelcomeService(){
// super(context);
// init_native();
}
public void setVal(int val){
setVal_native(val);
}
public int getVal(){
return getVal_native();
}
// private static native boolean init_native();
native static void setVal_native(int val);
native static int getVal_native();
}
3.2、将相应的server添加到系统server中:frameworks\base\services\java\com\android\server\SystemServer.java
在ServerThread::run函数中增加加载HelloService的代码:
@Override
public void run() {
....................................................................................
try{
Slog.i(TAG, "Welcome Service");
ServiceManager.addService("welcome",new WelcomeService());
}catch(Throwable e){
Slog.e(TAG,"Failure starting Welcome Service",e);
}
三、编译,打包下载
至此jni部分 实现完成,打包下载,看看能否正常开机,能正常开机没有异常,则成功了一半。