ok6410 android driver(12)
In this essay, I will talk about how to write the service libraries.
TIPS :
I won't discuss the name rules about HAL libraries, but it's quite important to our understanding.
You can check the source file :
android_source/hardware/libhardware/hardware.c
Or google with key word :
android hardware.c
1、Android.mk
In this file, it's important to write the LOCAL_SHARED_LIBRARIES and LOCAL_C_INCLUDE to assign the libraries for the service.
# Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) # [optional, user, eng]
# eng = required
# optinal = no install on target
LOCAL_MODULE_TAGS := eng # This is the target being built.
LOCAL_MODULE:= leds_hal_jni # Target install path.
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES) # All of the source files that we will compile.
LOCAL_SRC_FILES:= \
LedHalService.cpp # All of the shared libraries we link against.
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libcutils \
libhardware \
libhardware_legacy \
libnativehelper \
libsystem_server \
libutils \
libui \
libsurfaceflinger_client # Also need the JNI headers.
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
hardware/leds_hal # Don't prelink this library. For more efficient code, you may want
# to add this library to the prelink map and set this to true.
LOCAL_PRELINK_MODULE := false include $(BUILD_SHARED_LIBRARY)
2、LedHalService.cpp
Acturely, this file is the JNI file. Load the hal libraries (Use the hw_get_module function in hardware.c) and offer the API to android applications.
There are another methods array we should know is JNINativeMethod.
According the the native method, we could name the JNI functions ourselves without the long JNI default name.
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <jni.h> #include <leds_hal.h> struct leds_device_t *leds_device = NULL; static jboolean leds_setOn(JNIEnv *env, jobject thiz, jint led)
{
LOGI("Leds HAL JNI : leds_setOn() is invoked."); if (leds_device == NULL) {
LOGI("Leds HAL JNI : leds_device was not fetch correctly.");
return -;
} else {
return leds_device->set_on(leds_device, led);
}
} static jboolean leds_setOff(JNIEnv *env, jobject thiz, jint led)
{
LOGI("Leds HAL JNI : leds_setOff() is invoked."); if (leds_device == NULL) {
LOGI("Leds HAL JNI : leds_device was not fetch correctly.");
return -;
} else {
return leds_device->set_off(leds_device, led);
}
} static inline int leds_device_open(const struct hw_module_t* module,
struct leds_device_t** device)
{
return module->methods->open(module, LED_HARDWARE_MODULE_ID,
(struct hw_device_t**) device);
} static jboolean leds_init(JNIEnv *env, jclass clazz)
{
leds_module_t* module; LOGI(" >> finding HAL...");
LOGI("HAL id :"LED_HARDWARE_MODULE_ID); if (hw_get_module(LED_HARDWARE_MODULE_ID,
(const hw_module_t**) &module) == ) {
LOGI("LedService JNI : Led Stub found.");
if (leds_device_open(&module->hw_module,
&leds_device) == ) {
LOGI("LedService JNI : Got Stub operation.");
return ;
}
}
LOGE("LedService JNI : Get Stub operation failed.");
return -;
} static const JNINativeMethod methods[] = {
{ "_init", "()Z", (void *) leds_init },
{ "_set_on", "(I)Z", (void *) leds_setOn },
{ "_set_off", "(I)Z", (void *) leds_setOff },
}; int register_leds_hal(JNIEnv *env)
{
static const char* const kClassName = "mobile/android/leds/hal/service/LedHalService"; jclass clazz; clazz = env->FindClass(kClassName); if (clazz == NULL) {
LOGE("Can't find class %s.\n", kClassName);
return -;
} if (env->RegisterNatives(clazz, methods,
sizeof(methods)/sizeof(methods[]) != JNI_OK)) {
LOGE("Failed registing methods for %s.\n", kClassName);
return -;
} return ;
} jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv *env = NULL; if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE(" GetEnv failed!");
return -;
} register_leds_hal(env); return JNI_VERSION_1_4;
}
The prototype of JNINativeMethod :
typedef struct {
const char* name;
const char* signature;
void* fnPtr;
} JNINativeMethod;
TIPS :
In the LedHalService.cpp, we use #include <leds_hal.h> instead of #include "leds_hal.h", because of the Path was loaded in the Android.mk
After compiling, we should push the file leds_jni.so to dir /system/lib/ in ok6410.
Finaly, we write the Java program to call service library.
package mobile.android.leds.hal.service;
public class LedHalService {
private static LedHalService ledHalService; public static LedHalService getInstance() {
if (ledHalService == null)
return new LedHalService();
else
return ledHalService;
} private LedHalService() {
init();
} public boolean init() {
return _init();
} public boolean setOn(int led) {
return _set_on(led);
} public boolean setOff(int led) {
return _set_off(led);
} private native boolean _init();
private native boolean _set_on(int led);
private native boolean _set_off(int led); static {
System.load("/system/lib/leds_hal_jni.so");
}
}
What's more, this is a Java file and we can't use it directly. We stiil need to create an apk to call its jar file.
package com.example.leds_haljni; import mobile.android.leds.hal.service.LedHalService;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.CheckBox; public class MainActivity extends Activity {
private CheckBox[] cBox_leds = new CheckBox[4];
LedHalService ledHalService = LedHalService.getInstance(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); cBox_leds[0] = (CheckBox) findViewById(R.id.checkBox_led1);
cBox_leds[1] = (CheckBox) findViewById(R.id.checkBox_led2);
cBox_leds[2] = (CheckBox) findViewById(R.id.checkBox_led3);
cBox_leds[3] = (CheckBox) findViewById(R.id.checkBox_led4);
} public void onClick_switch(View view) { for (int i = 0; i < 4; i ++) {
if (cBox_leds[i].isChecked()) {
ledHalService.setOn(i);
} else {
ledHalService.setOff(i);
}
}
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }
Ok, here is the activity.xml and strings.xml :
(1) activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > <TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hal_hello" /> <CheckBox
android:id="@+id/checkBox_led1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/textView1"
android:layout_marginTop="14dp"
android:text="@string/led1" /> <Button
android:id="@+id/button_led"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/checkBox_led4"
android:layout_alignBottom="@+id/checkBox_led4"
android:layout_alignParentRight="true"
android:onClick="onClick_switch"
android:text="@string/button_led" /> <CheckBox
android:id="@+id/checkBox_led2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/checkBox_led1"
android:layout_alignBottom="@+id/checkBox_led1"
android:layout_alignRight="@+id/textView1"
android:layout_marginRight="26dp"
android:text="@string/led2" /> <CheckBox
android:id="@+id/checkBox_led3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/checkBox_led2"
android:layout_alignBottom="@+id/checkBox_led2"
android:layout_toRightOf="@+id/checkBox_led2"
android:text="@string/led3" /> <CheckBox
android:id="@+id/checkBox_led4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/checkBox_led3"
android:layout_alignBottom="@+id/checkBox_led3"
android:layout_marginLeft="34dp"
android:layout_toRightOf="@+id/checkBox_led3"
android:text="@string/led4" /> </RelativeLayout>
(2) strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources> <string name="app_name">ledshal</string>
<string name="action_settings">Settings</string>
<string name="hal_hello">This is a leds HAL application :</string>
<string name="led1">Led1</string>
<string name="led2">Led2</string>
<string name="led3">Led3</string>
<string name="led4">Led4</string>
<string name="button_led">Switch</string> </resources>
That's all about the simple Led Hal.
ok6410 android driver(12)的更多相关文章
- ok6410 android driver(5)
Test the android driver by JNI (Java Native Interface), In the third article, we know how to compile ...
- ok6410 android driver(11)
This essay, I go to a deeply studying to android HAL device driver program. According to the android ...
- ok6410 android driver(9)
In this essay, I will write the JNI to test our leds device. If you don't know how to create a jni p ...
- ok6410 android driver(8)
In the past, we know how to create and run a simple character device driver on pc, goldfish and ok64 ...
- ok6410 android driver(3)
This article discusses the Makefile and how to port the module to different platform (localhost and ...
- ok6410 android driver(10)
From this essay, we go to a new discussion "Android Hardware Abstraction Layer". In this e ...
- ok6410 android driver(7)
This article talk about how to test device driver on JNI. There are two ways to test the device driv ...
- ok6410 android driver(6)
This is a short essay about the mistakes in compiling ok6410 android-2.3 source codes. If there is n ...
- ok6410 android driver(1)
target system : Android (OK6410) host system : Debian Wheezy AMD64 1.Set up android system in ok6410 ...
随机推荐
- 100+诡异的数据集,20万Eclipse Bug、死囚遗言等
摘要:近日,Robert Seaton整理了100多个最有趣的数据集,其中包括Jeopardy真题,死囚的最后一句话,20万个Eclipse Bug,足球比赛相关,柏拉图式的爱情,太阳系以外的行星,1 ...
- 解决Electron加载带jquery的项目报错问题
<!-- Insert this line above script imports --> <script>if (typeof module === 'object') { ...
- SQL迁移到ORACLE实例
nohup ./command.sh > output 2>&1 & SQL迁移到ORACLE实例 日常运维中,我们经常会有数据库不同类型的迁移,比较多的就是从sql se ...
- THinkphp开启静态(动态)缓存的用法
<?php return array( //开启静态缓存 'HTML_CACHE_ON' => true, 'HTML_CACHE_RULES' => array( 'News:in ...
- 最近读的javascript,一些文章
本帖子是记录一些javascript的一些文章: 1. 理解node.js 2.异步编程 http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF% ...
- 有时候为了方便sql语句的对比和查询,我们可以使用declare来定义变量 上下篇的问题
--定义一些参数 declare @nodeId int,@ekid int ,@ecid int,@eid int,@pid int --列表 SELECT * FROM ( SELECT *,RO ...
- pip install使用豆瓣源
这个是老问题了 pip install -i https://pypi.douban.com/simple/ selenium 类似的,npm和gem安装的时候可以使用淘宝源.
- Navi.Soft30.产品.代码生成器.操作手册
1系统简介 1.1功能简述 在Net软件开发过程中,大部分时间都是在编写代码,并且都是重复和冗杂的代码.比如:要实现在数据库中10个表的增删改查功能,大部分代码都是相同的,只需修改10%的代码量.此时 ...
- 单元测试mock之mockito使用
先来一个简单的例子来感受一下 外部接口类:TestService.java package com.yzl.mock; /** * 测试用服务 * * @author yangzhilong */ p ...
- Python: 拷贝函数签名
使用场景有很多,比如C API在Python下很多都变成了(*args, **kwargs)的参数,这时候可能需要为其添加一个更严格签名来约束参数. 查了许多资料,能有效的拷贝函数签名貌似只能通过动态 ...