android hal学习——aidl,java service,jni编写

一、参考

二、代码
1、aidl相关
1)aidl文件定义
位置:
frameworks/base/core/java/android/os/IExampleService.aidl


package android.os;

interface IExampleService {
    void setVal(int val);
    int getVal();

}

2)、修改相应的Android.mk
vim frameworks/base/Android.mk
找到下面的这句话:

## READ ME: ########################################################
##
## When updating this list of aidl files, consider if that aidl is
## part of the SDK API.  If it is, also add it to the list below that
## is preprocessed and distributed with the SDK.  This list should
## not contain any aidl files for parcelables, but the one below should
## if you intend for 3rd parties to be able to send those objects
## across process boundaries.
##
## READ ME: ########################################################
LOCAL_SRC_FILES += \

在这个LOCAL_SRC_FILES后面增加:

    。。。    
        core/java/android/os/IExampleService.aidl \

3)、编译aidl

mmm frameworks/base/
...
n Runtime shutdown
[100% 8/8] Install: out/target/product/generic/system/framework/framework.jar
make: Leaving directory `/home/zzz/opensource/android-src'

#### make completed successfully (03:34 (mm:ss)) ####

2、服务端service相关
1)实现服务端service功能
参考文章提到是在frameworks/base/services/java/com/android/server建立ExampleService.java来实现aidl接口,应该是版本不同,我这边需要则在以下目录下实现:
frameworks/base/services/core/java/com/android/server。
代码照旧copy:

package com.android.server;

import android.content.Context;
import android.os.IExampleService;
import android.util.Slog;

public class ExampleService extends IExampleService.Stub {
    private static final String TAG = "ExampleService";

    private int mPtr = 0;

    ExampleService() {
        mPtr = init_native();

        if(mPtr == 0) {
            Slog.e(TAG, "Failed to initialize example service.");
        }
    }

    public void setVal(int val) {
        if(mPtr == 0) {
            Slog.e(TAG, "Example service is not initialized.");
            return;
        }
        setVal_native(mPtr, val);
    }

    public int getVal() {
        if(mPtr == 0) {
            Slog.e(TAG, "Example service is not initialized.");
            return 0;
        }

        return getVal_native(mPtr);
    }

    private static native int init_native();
    private static native void setVal_native(int ptr, int val);
    private static native int getVal_native(int ptr);
};

2)、编译该service

 mmm frameworks/base/services/core/
 。。。
 ============================================
Starting build with ninja
ninja: Entering directory `.'
[100% 5/5] build out/target/product/ge...rvices.core_intermediates/classes.jack
make: Leaving directory `/home/zzz/opensource/android-src'

#### make completed successfully (01:11 (mm:ss)) ####

3、jni相关
1)定义jni cpp文件
位置:frameworks/base/services/core/jni/com_android_server_ExampleService.cpp

#define LOG_TAG "ExampleServiceJNI"

#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/example.h>
#include <stdio.h>

namespace android
{
    static void example_setVal(JNIEnv* env, jobject clazz, jint ptr, jint value) {
        example_device_t* device = (example_device_t*)ptr;
        if(!device) {
            LOGE("Device example is not open.");
            return;
        }

        int val = value;
        LOGI("Set value %d to device example.", val);

        device->set_val(device, val);
    }

    static jint example_getVal(JNIEnv* env, jobject clazz, jint ptr) {
        example_device_t* device = (example_device_t*)ptr;
        if(!device) {
            LOGE("Device example is not open.");
            return 0;
        }

        int val = 0;

        device->get_val(device, &val);

        LOGI("Get value %d from device example.", val);

        return val;
    }
    static inline int example_device_open(const hw_module_t* module, struct example_device_t** device) {
        return module->methods->open(module, EXAMPLE_HARDWARE_DEVICE_ID, (struct hw_device_t**)device);
    }

    static jint example_init(JNIEnv* env, jclass clazz) {
        example_module_t* module;
        example_device_t* device;

        LOGI("Initializing HAL stub example......");

        if(hw_get_module(EXAMPLE_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) {
            LOGI("Device example found.");
            if(example_device_open(&(module->common), &device) == 0) {
                LOGI("Device example is open.");
                return (jint)device;
            }

            LOGE("Failed to open device example.");
            return 0;
        }

        LOGE("Failed to get HAL stub example.");

        return 0;
    }

    static const JNINativeMethod method_table[] = {
        {"init_native", "()I", (void*)example_init},
        {"setVal_native", "(II)V", (void*)example_setVal},
        {"getVal_native", "(I)I", (void*)example_getVal},
    };

    int register_android_server_ExampleService(JNIEnv *env) {
            return jniRegisterNativeMethods(env, "com/android/server/ExampleService", method_table, NELEM(method_table));
    }
};

2)修改onload.cpp代码,增加相关的函数:
vim frameworks/base/services/core/jni/onload.cpp

namespace android {
...
int register_android_server_ExampleService(JNIEnv* env);
};

extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
...
   register_android_server_ExampleService(env);

    return JNI_VERSION_1_4;
}

3)修改Android.mk文件
vim frameworks/base/services/core/jni/Android.mk
增加LOCAL_SRC_FILES的内容:

LOCAL_SRC_FILES += \
...
    $(LOCAL_REL_DIR)/com_android_server_ExampleService.cpp \
    $(LOCAL_REL_DIR)/onload.cpp \

4)编译
mmm frameworks/base/services/core/jni/


...
============================================
Starting build with ninja
ninja: Entering directory `.'
ninja: no work to do.
make: Leaving directory `/home/zzz/opensource/android-src'

#### make completed successfully (4 seconds) ####

4、将ExampleService加入到系统进程中
vim frameworks/base/services/java/com/android/server/SystemServer.java
增加:


 814 
 815 
 816 //-----------begin-----------------//
 817 try {
 818                 Slog.i(TAG, "Example Service");  
 819                 ServiceManager.addService("example", new ExampleService());     
 820             } catch (Throwable e) {
 821                 Slog.e(TAG, "Failure starting Example Service", e);
 822             }  
 823 //---------end---------//

5、重新编译frameworks/base/services模块:
mmm frameworks/base/services/
第一次编译出了点错误:

frameworks/base/services/core/jni/com_android_server_ExampleService.cpp:66:9: error: use of undeclared identifier 'LOGE'
        LOGE("Failed to get HAL stub example.");
        ^
9 errors generated.
ninja: build stopped: subcommand failed.
make: *** [ninja_wrapper] Error 1
make: Leaving directory `/home/zzz/opensource/android-src'

#### make failed to build some targets (01:32 (mm:ss)) ####

将com_android_server_ExampleService.cpp里面的LOGE改为ALOGE,LOGI改为ALOGI,再编译:
mmm frameworks/base/services/

No need to regenerate ninja file
Starting build with ninja
ninja: Entering directory `.'
[100% 19/19] build out/target/product/...interaction_intermediates/classes.jack
make: Leaving directory `/home/gumh/opensource/android-src'

#### make completed successfully (6 seconds) ####

6、修改权限
为了避免无权访问/dev/example,修改以下文件:
vim system/core/rootdir/ueventd.rc
在最后面增加:
/dev/example 0666 root root

7、重新生成system.img
make snod

。。。
make_ext4fs -T -1 -S out/target/product/generic/root/file_contexts.bin -L system -l 1610612736 -a system out/target/product/generic/system.img out/target/product/generic/system out/target/product/generic/system
Creating filesystem with parameters:
    Size: 1610612736
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 8192
    Inode size: 256
    Journal blocks: 6144
    Label: system
    Blocks: 393216
    Block groups: 12
    Reserved block group size: 95
Created filesystem with 1751/98304 inodes and 146362/393216 blocks
out/target/product/generic/system.img maxsize=1644333504 blocksize=2112 total=1610612736 reserve=16610880

#### make completed successfully (19 seconds) ####

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值