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

from:http://blog.csdn.net/brightming/article/details/49883469

一、参考

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


package android.os;

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

}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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 += \


 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这个LOCAL_SRC_FILES后面增加:

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

 
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

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)) ####

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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);
};


 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

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)) ####
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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));
    }
};

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

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;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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 \
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

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) ####

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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---------//
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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)) ####


 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

将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) ####
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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) ####

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 12 中,C++ ServiceAIDLHAL 仍然是 Android 系统中重要的组成部分。 1. C++ Service C++ ServiceAndroid 系统中的一种基于 Binder 机制实现的服务。它可以在 Android 系统启动时启动,并提供某些系统级别的服务,例如音频服务、电源管理服务等等。 C++ Service 主要的实现语言是 C++,开发者可以使用 C++ 语言来编写自己的 C++ Service。要编写一个 C++ Service,开发者需要实现一个继承自 IInterface 的接口类,并在其中实现自己的服务逻辑。然后,开发者需要通过 ServiceManager 将自己的服务注册到系统中。 2. AIDL AIDLAndroid Interface Definition Language)是 Android 系统中的一种 RPC(Remote Procedure Call)框架,它可以用于在不同的进程之间进行通信。开发者可以使用 AIDL 来定义自己的接口,并通过 Binder 机制将接口暴露给客户端。 AIDL 语言是一种类似于 Java 的语言,开发者可以使用 AIDL 来定义自己的接口、数据类型和异常。在使用 AIDL 时,开发者需要编写一个 AIDL 文件,然后通过 AIDL 工具来生成对应的 Java 接口文件和 C++ 接口文件。在编写服务端和客户端时,开发者需要分别实现 Java 接口和 C++ 接口。 3. HAL HAL(Hardware Abstraction Layer)是 Android 系统中的一种硬件抽象层。它可以将硬件接口和实现分离,使得不同厂商可以实现自己的硬件适配层。开发者可以使用 HAL 来访问硬件设备,例如摄像头、传感器等等。 HAL 主要的实现语言是 C++,开发者可以使用 C++ 语言来编写自己的 HAL。要编写一个 HAL,开发者需要实现自己的 HAL 接口,并在其中实现自己的硬件逻辑。然后,开发者需要将自己的 HAL 注册到系统中,使得其他应用程序可以使用它。 以上就是 Android 12 中 C++ ServiceAIDLHAL 的一些基本介绍。这些技术都是 Android 系统中非常重要的组成部分,开发者需要深入了解它们的使用方法和原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值