NEED --------》 AIDL JNI SystemServer HAL
需求:添加上层通过调用接口方法,更改硬件设备的状态、启动功能。
分为三个部分的工作
1、添加一个Android源码添加自定义系统服务,提供给应用层api
(1) 在源码frameworks/base/core/java/android/os/ 下面新增 一个 IMyService.aidl
package android.os;
interface IMyService {
void setVal(String key,String value);
String getVal(String key);
void open();
void close();
//根据需求添加控制硬件的方法
}
(2) /frameworks/base/Android.mk 添加aidl
LOCAL_SRC_FILES += \
....
core/java/android/os/IMyService.aidl \
.....
(3)在 frameworks/base/services/core/java/com/android/server/ 下面新增一个 MyService.java 用来实现aidl文件定义的接口。
package com.android.server;
import android.os.IMyService;
public class MyService extends IMyService.Stub {
public MyService() {
}
@Override
public void setVal(String key, String value) throws RemoteException {
return native_setVal();
//这里去调用JNI方法
}
@Override
public String getVal(String key) throws RemoteException {
return native_getVal();
}
....
//根据自己的需求添加
}
(4)/frameworks/base/services/java/com/android/server/SystemServer.java 添加自定义MyService系统服务到systemservice
private void startOtherServices() {
.....
//xxxx add end
Slog.i(TAG, "My Service");
ServiceManager.addService("myxxxx", new MyService());
.....
}
这样你就可以直接调用服务来使用自定义系统服务的方法了
(5)先添加aidl到你的使用服务的上层app中,文件和frameworks/base/core/java/android/os/添加的aidl一模一样
(如果你没有在源码里编译而是单独编译又签名放到源码里的,可以用反射写)
IBinder b = ServiceManager.getService("myxxxx");
IMyService service = IMyService.Stub.asInterface(b);
s = service .getVal();
当然你还可以再封装成manager方便使用
在frameworks/base/core/java/android/app/ 下创建MyxxxManager.java 文件
package android.app;
.....
import android.os.IMyService;
public class MyxxxManager {
IMyService mService;
public MyxxxManager (Context ctx,IMyService service){
mService=service;
}
public void open(){
try{
mService.open();
}catch(Exception e){
e.printStackTrace();
}
}
......
根据自己需求添加方法,控制设备开关等
}
修改frameworks/base/core/java/android/app/SystemServiceRegistry.java
registerService("myxxxx", MyxxxManager.class,
new CachedServiceFetcher<MyxxxManager>() {
@Override
public MyManagercreateService(ContextImpl ctx) {
IBinder b = ServiceManager.getService("myxxxx");
IMyService service = IMyService .Stub.asInterface(b);
return new MyxxxManager(ctx, service);
}});
2、JNI承上启下
/frameworks/base/services/core/jni/Android.mk
LOCAL_SRC_FILES += \
...
$(LOCAL_REL_DIR)/com_android_server_MyService.cpp \
....
/frameworks/base/services/core/jni/com_android_server_MyService.cpp
这里根据自己的需求去写,jni调hal
#define LOG_TAG "MyService"
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <binder/IServiceManager.h>
#include <utils/misc.h>
#include <utils/Log.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <hardware/myxxx_hal.h>
namespace android
{
static myxxx_device_t* myxxx_device;
static inline int myxxx_device_open(const hw_module_t* module, struct myxxx_device_t** device) {
return module->methods->open(module, XXX_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
}
}
jint mOpen(JNIEnv *env, jobject cls)
{
jint err;
xxx_module_t* module;
xxx_device_t* device;
if(hw_get_module("MYXXX", (hw_module_t const**)&module)==0)
{
err = myxxx_device_open(&(module->common), &device);
if (err == 0) {
xxx_device = (xxx_device_t *)device;
return 0;
} else {
return -1;
}
}
return -1;
}
void mClose(JNIEnv *env, jobject cls)
{
//close(fd);
}
jint mSetv(JNIEnv *env, jobject cls,jint index)
{
return xxx_device->xxx_setval(xxx_device,index);
}
jint mGetv(JNIEnv *env, jobject cls,jint index)
{
return xxx_device->xxx_Getval();
}
.....
static const JNINativeMethod methods[] = {
{"native_open", "()I", (void *)mOpen},
{"native_close", "()V", (void *)mClose},
{"native_getVal", "()I", (void *)mGetv},
{"native_setVal", "(I)I", (void *)mSetv},
};
int register_android_server_MyService(JNIEnv *env)
{
return jniRegisterNativeMethods(env, "com/android/server/MyService",
methods, NELEM(methods));
}
}
/frameworks/base/services/core/jni/onload.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.
*/
#include "JNIHelp.h"
#include "jni.h"
#include "utils/Log.h"
#include "utils/misc.h"
namespace android {
int register_android_server_AlarmManagerService(JNIEnv* env);
....
//xxxxx add
int register_android_server_MyService(JNIEnv* env);
};
using namespace android;
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
JNIEnv* env = NULL;
jint result = -1;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
ALOGE("GetEnv failed!");
return result;
}
ALOG_ASSERT(env, "Could not retrieve the env!");
register_android_server_PowerManagerService(env);
...
//xxxxx add
register_android_server_MyService(env);
return JNI_VERSION_1_4;
}
3、HAL
然后就是就是jni调用hal的东西了,说实话hal我就不懂了,这里是我们驱动工程师去编写的,大致如下仅供参考
/hardware/libhardware/include/hardware/myxxx_hal.h
/hardware/libhardware/modules/myxxx/myxxx_hal.c
/hardware/libhardware/modules/myxxx/Android.mk
编译生成.so 或者.a,jni调用
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myxxx.default
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_C_INCLUDES := hardware/libhardware
LOCAL_SRC_FILES := myxxx_hal.c
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_MODULE_TAGS := eng
include $(BUILD_SHARED_LIBRARY)
/hardware/libhardware/modules/Android.mk
hardware_modules := gralloc hwcomposer audio nfc nfc-nci local_time \
power usbaudio audio_remote_submix camera usbcamera consumerir sensors vibrator \
tv_input fingerprint input \
# add
myxxx
include $(call all-named-subdir-makefiles,$(hardware_modules))
hal到硬件控制就是各种厂商做的
这样完整的一套流程就ok了。
从驱动层到framwork再到app api使用。