从LINUX 驱动 到APK (3)

实现相应的JNI部分已经sever部分

  此次实现主要涉及的修改两个目录的文件 hardware,以及framework。

  一、修改hardware目录:

  由于平台原因,使用的主要是hardwarelibhardware_legacy 目录下的文件,接口为老的接口,不同于老罗使用的相关,自己写代码可以参考vibrator 马达的实现。

  添加头文件hardwarelibhardware_legacyincludehardware_legacywelcome.h

  

#ifndef _ANDROID_WELCOME_INTERFACE_H_
#define _ANDROID_WELCOME_INTERFACE_H_

#if 1
#if __cplusplus
extern "C" {
#endif
// 定义模块ID
//#define WELCOME_HARDWARE_MODULE_ID "welcome"
//硬件接口结构体
int set_val(const char *sysfs_path,int val);
int get_val(const char *sysfs_path,int* val);

#if __cplusplus
}  // extern "C"
#endif
#endif
#endif //__ANDROID_WELCOME_INTERFACE_H__

  2、添加相应的实现文件hardwarelibhardware_legacy

   2.1 在此目录先新建welcome 目录用于统一管理本次hal层代码,并添加相关Android.mk 文件添加编译规则    

    LOCAL_SRC_FILES += welcome/welcome.c

  2.2 添加实现文件welcome.c

#define LOG_TAG "welcomeStub"

#include <hardware/hardware.h>
#include <hardware_legacy/welcome.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <cutils/log.h>
#include <cutils/atomic.h>

#define DEVICE_NAME "/dev/welcomf"

#define MODULE_AUTHOR "atlas_li@126.com"

//设备访问接口
int welcome_set_val(char *sysfs_path,int val);
int welcome_get_val(char *sysfs_path,int* val);



//设备打开和关闭接口
int welcome_device_open(const struct hw_module_t* module,const char* name, struct hw_device_t** device){
    return 0;
}
int welcome_device_close(struct hw_device_t* device){
    return 0;
}
//设备访问接口
int set_val(const char *sysfs_path,int val){
    int fd;
    if((fd = open(DEVICE_NAME,O_RDWR)) == -1){
        ALOGE("Welcome Staub : failed to open %s .%m",DEVICE_NAME);

        return -EFAULT;
    }

    ALOGI("Welcome Stub: set value %d to device.",val);
    write(fd,&val,sizeof(val));
    close(fd);

    return 0;    
}
int get_val(const char *sysfs_path,int* val){
    int fd;
    if((fd = open(DEVICE_NAME,O_RDWR)) == -1){
        ALOGE("Welcome Staub : failed to open %s .%m",DEVICE_NAME);

        return -EFAULT;
    }
    if(!val){
        ALOGE("Welcome Stube: error val pointer");
        return -EFAULT;
    }
    read(fd,val,sizeof(*val));
    ALOGI("Welcome Stub: get value %d from device",*val);

    close(fd);
    return 0;
}

  此部分耗时比较常,按老罗的方式,添加会导致手机不能正常开机一直停留在开机动画过程,故借鉴此平台的马达实现部分对代码进行修改。

  2.3 将相应的代码合入到对应的库文件中修改hardwarelibhardware_legacyAndroid.mk  添加对应模块welcome

    legacy_modules := power uevent vibrator wifi qemu qemu_tracing welcome 

    

   二、修改framework部分

    此部分主要包含以下几个部分的实现:实现相应的JNI文件,实现相应的aidl文件,实现相关的server文件,配置相关文件让jni与server正常工作

   1、实现相应的JNI文件:  frameworksaseservicescorejni

    1.1、使用相应的jni文件:com_android_server_WelcomeService.cpp

/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#if 1
#define LOG_TAG "WelcomeService"

#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"

#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware_legacy/welcome.h>

#include <stdio.h>

namespace android
{
const char* DEVICE_PATH ="/dev/welcomf" ;

// 通过硬件抽象层定义的硬件访问接口设置硬件寄存器val的值
static void welcome_setVal(JNIEnv *env, jobject clazz,jint value){
    int val = value;
    ALOGI("Welcome JNI: set value %d to device.",val);
    set_val(DEVICE_PATH,val);
}
//通过硬件抽象定义的硬件访问接口读取硬件寄存器val 值
static jint welcome_getVal(JNIEnv *env, jobject clazz){
    int val = 0;
    get_val(DEVICE_PATH,&val);

    ALOGI("Welcome JNI: get value %d from device.",val);
    return val;
}
//通过硬件抽象层定义的硬件模块打开接口打开硬件设备 vib 在hardware h文件中
/*static inline int welcome_device_open(const hw_module_t* module,struct welcome_device_t** device){
    return module->methods->open(module,WELCOME_HARDWARE_MODULE_ID,(struct hw_device_t**)device);
}*/

//通过硬件模块ID 来加载指定的在硬件模块并打开硬件
static jboolean welcome_init(JNIEnv *env, jobject clazz){
    ALOGI("Welcome JNI :initializing...... ");


    return 0;
}
//JNI 方法表
static JNINativeMethod method_table[] = {
//    {"init_native","()Z",(void *)welcome_init},
    {"setVal_native","(I)V",(void *)welcome_setVal},
    {"getVal_native","()I",(void *)welcome_getVal},
};

//JNI 注册
int register_android_server_WelcomeService(JNIEnv *env){
    return jniRegisterNativeMethods(env,"com/android/server/WelcomeService",method_table,NELEM(method_table));
}


};//namespace android
#endif

    1.2、修改编译规则,让jni参与编译,已经调用

      1.2.1、修改该目录下的Android.mk 文件 在LOCAL_SRC_FILES += 增加一行

    LOCAL_SRC_FILES +=

  .................

    $(LOCAL_REL_DIR)/com_android_server_WelcomeService.cpp

    1.2.2、添加相关调用,修改同目录下的:onload.cpp      

    首先在namespace android增加register_android_server_WelcomeService函数声明:
    namespace android {
      ..............................................................................................
      int register_android_server_WelcomeService(JNIEnv *env);
    在JNI_onLoad增加register_android_server_HelloService函数调用:
      extern "C" jint JNI_onLoad(JavaVM* vm, void* reserved){
        .................................................................................................
        register_android_server_WelcomeService(env);

   2、实现相应的aidl文件

    .1、frameworksasecorejavaandroidosIWelcomeService.aidl    

/**
 * Copyright (c) 2007, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.os;

/** {@hide} */

interface IWelcomeService
{
   void setVal(int val);
   int getVal();
}

    2.2、添加入编译规则 frameworksaseAndroid.mk

      LOCAL_SRC_FILES +=  

      ..........

        core/java/android/os/IWelcomeService.aidl

   3、实现相关的server文件

     3.1、实现相应的server文件:frameworksaseservicescorejavacomandroidserverWelcomeService.java

/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server;

//import android.app.AppOpsManager;
//import android.content.BroadcastReceiver;
import android.content.Context;

import android.os.IWelcomeService;
import com.android.server.SystemService;
import android.app.Service;

import android.util.Slog;


public class WelcomeService extends IWelcomeService.Stub{
    private static final String TAG = "WelcomeService";
    WelcomeService(){
//        super(context);
    //    init_native();
    }
    public void setVal(int val){
        setVal_native(val);
    }
    public int getVal(){
        return getVal_native();
    }
//    private static native boolean init_native();
    native static  void setVal_native(int val);
    native static  int getVal_native();
}

    3.2、将相应的server添加到系统server中:frameworksaseservicesjavacomandroidserverSystemServer.java      

      在ServerThread::run函数中增加加载HelloService的代码:
        @Override
        public void run() {
        ....................................................................................

        try{
            Slog.i(TAG, "Welcome Service");
            ServiceManager.addService("welcome",new WelcomeService());
        }catch(Throwable e){
            Slog.e(TAG,"Failure starting Welcome Service",e);
        }
    

    三、编译,打包下载

      至此jni部分 实现完成,打包下载,看看能否正常开机,能正常开机没有异常,则成功了一半。 

原文地址:https://www.cnblogs.com/atlas2016/p/7574570.html