6. Android10向系统注册service访问硬件抽象层(HAL)模块

本文是在上文5. Android10增加硬件抽象层(HAL)模块访问内核驱动程序的基础上进行的,虚拟机环境就是上文结束时的环境。

实现HelloService

在aosp10/frameworks/base/core/java/android/os/目录下新建IHelloService.aidl文件

package android.os;  

interface IHelloService {  
    int wirteString(String str);  
    String readString();  
}

在aosp10/frameworks/base/services/core/java/com/android/server目录下新建HelloService.java文件

package com.android.server;  
import android.content.Context;  
import android.os.IHelloService;  
import android.util.Slog;  
public class HelloService extends IHelloService.Stub {  
    private static final String TAG = "HelloService";  
    HelloService() {  
        init_native();  
    }    
    public int wirteString(java.lang.String str){
    return wirteString_native(str);
    }
    public java.lang.String readString() {  
       return readString_native();  
    }  

    private static native boolean init_native();  
    private static native int wirteString_native(String str);  
    private static native String readString_native();  
}; 

修改aosp10/frameworks/base目录下的Android.bp,增加一行

"core/java/android/os/IHelloService.aidl",

 添加jni接口访问HAL层

HelloService通过init_native()、wirteString_native(String str)、readString_native()这三个jni函数来访问HAL层,这里来实现这三个jni函数。

在aosp10/frameworks/base/services/core/jni目录下新建com_android_server_HelloService.cpp文件

#define LOG_TAG "HelloService"
#include <nativehelper/JNIHelp.h>
#include "jni.h"
#include <utils/Log.h>
#include <utils/misc.h>
#include <utils/String8.h>
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <linux/ioctl.h>
#include <linux/rtc.h>
#include <hardware/hello.h>
namespace android {
	//jstring to char*
	char* jstringTostring(JNIEnv* env, jstring jstr);
	//char* to jstring
	jstring stoJstring(JNIEnv* env, const char* pat);
	/*在硬件抽象层中定义的硬件访问结构体,参考<hardware/hello.h>*/
	struct hello_device_t* device = NULL;
	/*通过硬件抽象层定义的硬件访问接口读字符串*/
	static jstring hello_readString(JNIEnv* env, jobject clazz) {
		if(!device) {
			ALOGI("Hello JNI: device is not open.");
			return NULL;
		}
		char read_str[VAL_LENGTH];
		device->read_string(device, (char *)&read_str);
		ALOGI("Hello JNI: read string %s from hello device.", read_str);
		return stoJstring(env,read_str);
	}
	/*通过硬件抽象层定义的硬件访问接口写字符串*/
	static jint hello_writeString(JNIEnv* env, jobject clazz,jstring str) {
		if(!device) {
			ALOGI("Hello JNI: device is not open.");
			return -1;
		}
		char * local_str = jstringTostring(env,str);
		device->write_string(device, local_str);
		ALOGI("Hello JNI: write string %s to hello device.", local_str);
		return strlen(local_str);
	}
	/*通过硬件抽象层定义的硬件模块打开接口打开硬件设备*/
	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);
	}
	/*通过硬件模块ID来加载指定的硬件抽象层模块并打开硬件*/
	static jboolean hello_init(JNIEnv* env, jclass clazz) {
		hello_module_t* module;
		ALOGI("Hello JNI: initializing......");
		if(hw_get_module(HELLO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) {
			ALOGI("Hello JNI: hello Stub found.");
			if(hello_device_open(&(module->common), &device) == 0) {
				ALOGI("Hello JNI: hello device is open.");
				return 0;
			}
			ALOGI("Hello JNI: failed to open hello device.");
			return -1;
		}
		ALOGI("Hello JNI: failed to get hello stub module.");
		return -1;
	}
	/*JNI方法表*/
	static const JNINativeMethod method_table[] = { {
			"init_native", "()Z", (void*)hello_init
		}
		, {
			"readString_native", "()Ljava/lang/String;", (void*)hello_readString
		}
		, {
			"wirteString_native", "(Ljava/lang/String;)I", (void*)hello_writeString
		}
		,
	}
	;
	/*注册JNI方法*/
	int register_android_server_HelloService(JNIEnv *env) {
		ALOGI("SystemServer :register_android_server_HelloService.");
		return jniRegisterNativeMethods(env, "com/android/server/HelloService", method_table, NELEM(method_table));
	}
	//jstring to char*
	char* jstringTostring(JNIEnv* env, jstring jstr) {
		char* rtn = NULL;
		jclass clsstring = env->FindClass("java/lang/String");
		jstring strencode = env->NewStringUTF("utf-8");
		jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
		jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
		jsize alen = env->GetArrayLength(barr);
		jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
		if (alen > 0) {
			rtn = (char*)malloc(alen + 1);
			memcpy(rtn, ba, alen);
			rtn[alen] = 0;
		}
		env->ReleaseByteArrayElements(barr, ba, 0);
		return rtn;
	}
	//char* to jstring
	jstring stoJstring(JNIEnv* env, const char* pat) {
		jclass strClass = env->FindClass("java/lang/String");
		jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
		jbyteArray bytes = env->NewByteArray(strlen(pat));
		env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
		jstring encoding = env->NewStringUTF("utf-8");
		return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
	}
};

修改aosp10/frameworks/base/services/core/jni目录下的Android.bp文件

        "com_android_server_HelloService.cpp",

修改aosp10/frameworks/base/services/core/jni目录下的onload.cpp

int register_android_server_HelloService(JNIEnv* env);

// ......

    register_android_server_HelloService(env);

 

向系统注册HelloService

 在aosp10/frameworks/base/core/java/android/app/目录下新建HelloManager.java文件

package android.app;
 
 
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.IHelloService;
import android.util.Log;
 
public class HelloManager {
    IHelloService mService;
    public HelloManager(Context ctx,IHelloService service){
        mService = service;
    }
    public void wirteString(String value){
        try{
			Log.e("HelloManager","HelloManager wirteString");
            mService.wirteString(value);
        }catch(Exception e){
            Log.e("HelloManager",e.toString());
            e.printStackTrace();
        }
 
    }
    public String readString(){
        try{
			Log.e("HelloManager","HelloManager readString");
            return mService.readString();
        }catch(Exception e){
            Log.e("HelloManager",e.toString());
            e.printStackTrace();
        }
        return null;
    }
}

修改aosp10/frameworks/base/core/java/android/app/SystemServiceRegistry.java文件

import android.os.IHelloService;

......

        registerService("hello", HelloManager.class,
        new CachedServiceFetcher<HelloManager>() {
            @Override
            public HelloManager createService(ContextImpl ctx)
                    throws ServiceNotFoundException {
                IBinder b = ServiceManager.getServiceOrThrow(
                        "hello");
                return new HelloManager(ctx, IHelloService.Stub.asInterface(b));
            }});

修改aosp10/frameworks/base/services/java/com/android/server目录下的SystemServer.java文件

import com.android.server.HelloService;

// ......

            traceBeginAndSlog("StartHelloService");
            try {
                ServiceManager.addService("hello", new HelloService());
            } catch (Throwable e) {
                reportWtf("starting HelloService", e);
            }
            traceEnd();

为HelloService添加selinux权限

首先需要修改这3个文件 

aosp10/system/sepolicy/public/property_contexts
aosp10/system/sepolicy/prebuilts/api/28.0/public/property_contexts
aosp10/system/sepolicy/prebuilts/api/29.0/public/property_contexts

在每个文件中添加一行

ro.hardware.hello u:object_r:exported_default_prop:s0 exact string

 

 第二步,修改aosp10/system/sepolicy/vendor/file_contexts文件,添加一行

/(vendor|system/vendor)/lib(64)?/hw/hello\.default\.so                                u:object_r:same_process_hal_file:s0

第三步 ,修改service_contexts和service.te文件,一共有10个文件,分为5组,每组都有service_contexts和service.te两个文件

aosp10/system/sepolicy/private/service_contexts
aosp10/system/sepolicy/public/service.te

aosp10/system/sepolicy/prebuilts/api/26.0/private/service_contexts
aosp10/system/sepolicy/prebuilts/api/26.0/public/service.te

aosp10/system/sepolicy/prebuilts/api/27.0/private/service_contexts
aosp10/system/sepolicy/prebuilts/api/27.0/public/service.te

aosp10/system/sepolicy/prebuilts/api/28.0/private/service_contexts
aosp10/system/sepolicy/prebuilts/api/28.0/public/service.te

aosp10/system/sepolicy/prebuilts/api/29.0/private/service_contexts
aosp10/system/sepolicy/prebuilts/api/29.0/public/service.te

所有的 service_contexts文件添加一行

hello                                     u:object_r:hello_service:s0

 所有的 service.te文件添加一行

type hello_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;

编译 


cd ~/Documents/aosp10
export TARGET_PREBUILT_KERNEL=/home/test/Documents/msm/arch/arm64/boot/Image.lz4-dtb
source build/envsetup.sh
lunch
aosp_walleye-userdebug
mm ./frameworks/base/

本文涉及到的知识主要和Android架构中的应用程序框架层、系统运行库层、硬件抽象层相关

 参考

Android应用程序访问linux驱动第三步:实现并向系统注册Service_阳光玻璃杯-CSDN博客

在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口_老罗的Android之旅-CSDN博客

在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务_老罗的Android之旅-CSDN博客

AndroidQ 从app到驱动 第三章 SystemServer服务中添加 HelloService_长乐居士-CSDN博客

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值