In the two articles, we covered how to write drivers for the Android system hardware, including how to implement kernel drivers in Linux kernel space and the hardware abstraction layer interface in user space. To achieve the purpose of both is to provide hardware to access interface layer on more, that is the Android Application Frameworks layer provides hardware service. We know that the application from the Android system is written in Java, and hardware drivers are using C language to achieve, then, how Java interfaces to access the C interface it? As we all know, Java JNI provides a method call, Similarly, in the Android system, Java applications to invoke hardware abstraction layer interface through JNI. In this article, we'll show you how to write an interface JNI method for the Android hardware abstraction layer so that the upper layer of Java applications to use the services provided by the underlying hardware.
"Android system source code Scenario Analysis," a book under attack programmer network ( http://0xcc0xcd.com in) serial, click to enter!
A reference to an increase in the Ubuntu for Android hardware abstraction layer (HAL) Linux kernel driver module to access a file, ready hardware abstraction layer module, to ensure that the Android system image file already contains hello.default system.img module.
Second into the frameworks / base / services / jni directory, create com_android_server_HelloService.cpp file:
USER-NAME@MACHINE-NAME:~/Android$ cd frameworks/base/services/jni
USER-NAME@MACHINE-NAME:~/Android/frameworks/base/services/jni$ vi com_android_server_HelloService.cpp
In com_android_server_HelloService.cpp document, implement JNI method. CAUTION command file, com_android_server prefix indicates that the package name, a hardware service HelloService is placed under the com frameworks / base / services / java directory / android / server directory, that there is a command com.android.server. HelloService class. Here, we have omitted describe HelloService class, the next article, we will return to HelloService class. Simply put, HelloService is a Java interface provides hardware access service class.
The first is to include the appropriate header files:
-
#define LOG_TAG "HelloService"
-
#include "jni.h"
-
#include "JNIHelp.h"
-
#include "android_runtime/AndroidRuntime.h"
-
#include <utils/misc.h>
-
#include <utils/Log.h>
-
#include <hardware/hardware.h>
-
#include <hardware/hello.h>
-
#include <stdio.h>
It then defines hello_init, hello_getVal and hello_setVal three JNI method:
-
namespace android
-
{
-
/ * Hardware access structures defined in hardware abstraction layer, the reference <hardware / hello.h> * /
-
struct hello_device_t* hello_device = NULL;
-
/ * Hardware access interface hardware registers provided by hardware abstraction layer val defined value * /
-
static void hello_setVal(JNIEnv* env, jobject clazz, jint value) {
-
int val = value;
-
LOG (
"Hello JNI: set value %d to device.", val);
-
if(!hello_device) {
-
LOG (
"Hello JNI: device is not open.");
-
return;
-
}
-
-
hello_device->set_val(hello_device, val);
-
}
-
/ * Read the hardware register access interface hardware val hardware abstraction layer defined by the value of * /
-
static jint hello_getVal(JNIEnv* env, jobject clazz) {
-
int val =
0;
-
if(!hello_device) {
-
LOG (
"Hello JNI: device is not open."
);
-
return val;
-
}
-
hello_device->get_val(hello_device, &val);
-
-
LOG (
"Hello JNI: get value %d from device.", val);
-
-
return
val;
-
}
-
/ * Hardware abstraction layer defined open interface to open a hardware module hardware * /
-
static inline int hello_device_open(const hw_module_t* module, struct hello_device_t** device) {
-
return
module->methods->open(
module, HELLO_HARDWARE_MODULE_ID, (struct
hw_device_t**)device);
-
}
-
/ * Hardware module ID to load the specified hardware abstraction layer module and open hardware * /
-
static jboolean hello_init(JNIEnv* env, jclass clazz) {
-
hello_module_t*
module;
-
-
LOG (
"Hello JNI: initializing......");
-
if(hw_get_module(HELLO_HARDWARE_MODULE_ID, (
const struct
hw_module_t**)&
module) ==
0) {
-
LOG (
"Hello JNI: hello Stub found.");
-
if(hello_device_open(&(
module->common), &hello_device) ==
0) {
-
LOG (
"Hello JNI: hello device is open.");
-
return
0;
-
}
-
LODGE (
"Hello JNI: failed to open hello device.");
-
return
-1;
-
}
-
LODGE (
"Hello JNI: failed to get hello stub module.");
-
return
-1;
-
}
-
/ * JNI method table * /
-
static
const JNINativeMethod method_table[] = {
-
{
"init_native",
"()Z", (
void*)hello_init},
-
{
"setVal_native",
"(I)V", (
void*)hello_setVal},
-
{
"getVal_native",
"()I", (
void*)hello_getVal},
-
};
-
/ * Register JNI method * /
-
int register_android_server_HelloService(JNIEnv *env) {
-
return jniRegisterNativeMethods(env,
"com/android/server/HelloService", method_table, NELEM(method_table));
-
}
-
};
Note that, in hello_init function, hw_get_module Android method provided by the hardware abstraction layer for the load module ID HELLO_HARDWARE_MODULE_ID hardware abstraction layer module, wherein, HELLO_HARDWARE_MODULE_ID defined in <hardware / hello.h> of. Android based hardware abstraction layer to find the corresponding module in the system Android / system / lib / hw directory HELLO_HARDWARE_MODULE_ID value, and then load them, and the interface returns to the caller hw_module_t use. In jniRegisterNativeMethods function, the value of the second parameter is the path corresponding to the package must be located HelloService, i.e. com.android.server.HelloService.
Three onload.cpp modify files in the same directory, first in the namespace android increase register_android_server_HelloService function declaration:
namespace android {
..............................................................................................
int register_android_server_HelloService(JNIEnv *env);
};