android 自定义 上层API控制硬件设备的一种完整过程实现

NEED --------》  AIDL    JNI     SystemServer     HAL

需求:添加上层通过调用接口方法,更改硬件设备的状态、启动功能。

分为三个部分的工作

1、添加一个Android源码添加自定义系统服务,提供给应用层api

 (1) 在源码frameworks/base/core/java/android/os/ 下面新增 一个 IMyService.aidl

package android.os;

interface IMyService {
   void setVal(String key,String value);
   String getVal(String key);
   void open();
   void close();
//根据需求添加控制硬件的方法

}

 (2)  /frameworks/base/Android.mk 添加aidl

LOCAL_SRC_FILES += \
....
core/java/android/os/IMyService.aidl \
.....

 (3)在 frameworks/base/services/core/java/com/android/server/ 下面新增一个 MyService.java 用来实现aidl文件定义的接口。

package com.android.server;

import android.os.IMyService;

public class MyService extends IMyService.Stub {

    public MyService() {

    }

    @Override
    public void setVal(String key, String value) throws RemoteException {         
            return native_setVal();
//这里去调用JNI方法
    }

    @Override
    public String getVal(String key) throws RemoteException {
        return native_getVal();
    }
....
//根据自己的需求添加
}

 (4)/frameworks/base/services/java/com/android/server/SystemServer.java 添加自定义MyService系统服务到systemservice

   private void startOtherServices() {
.....
    		//xxxx add end
			Slog.i(TAG, "My Service");           
            ServiceManager.addService("myxxxx", new MyService());

.....
}

这样你就可以直接调用服务来使用自定义系统服务的方法了

 (5)先添加aidl到你的使用服务的上层app中,文件和frameworks/base/core/java/android/os/添加的aidl一模一样

 (如果你没有在源码里编译而是单独编译又签名放到源码里的,可以用反射写)

  IBinder b = ServiceManager.getService("myxxxx");
  IMyService service = IMyService.Stub.asInterface(b);
   s = service .getVal();

当然你还可以再封装成manager方便使用

在frameworks/base/core/java/android/app/ 下创建MyxxxManager.java 文件

package android.app;
.....

import android.os.IMyService;


public class MyxxxManager {
    IMyService mService;
    public MyxxxManager (Context ctx,IMyService service){
        mService=service;
    }
    public void open(){
        try{
            mService.open();
        }catch(Exception e){
            e.printStackTrace();
        }

    }
   
      ......
        根据自己需求添加方法,控制设备开关等
}

修改frameworks/base/core/java/android/app/SystemServiceRegistry.java

registerService("myxxxx", MyxxxManager.class,
                new CachedServiceFetcher<MyxxxManager>() {
                    @Override
                    public MyManagercreateService(ContextImpl ctx) {
                        IBinder b = ServiceManager.getService("myxxxx");
                        IMyService service = IMyService .Stub.asInterface(b);
                        return new MyxxxManager(ctx, service);
                    }});

2、JNI承上启下

/frameworks/base/services/core/jni/Android.mk

LOCAL_SRC_FILES += \
    ...
	$(LOCAL_REL_DIR)/com_android_server_MyService.cpp \

....

/frameworks/base/services/core/jni/com_android_server_MyService.cpp

这里根据自己的需求去写,jni调hal

#define LOG_TAG "MyService"

#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <binder/IServiceManager.h>

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

#include <stdio.h>

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <hardware/myxxx_hal.h>

namespace android
{
static myxxx_device_t* myxxx_device;

static inline int myxxx_device_open(const hw_module_t* module, struct myxxx_device_t** device) {
		return module->methods->open(module, XXX_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
	}

	}

jint mOpen(JNIEnv *env, jobject cls)
{	
	jint err;
    xxx_module_t* module;
	xxx_device_t* device;

  if(hw_get_module("MYXXX", (hw_module_t const**)&module)==0)
  {		
	    err =  myxxx_device_open(&(module->common), &device);
	    if (err == 0) {		
	        xxx_device = (xxx_device_t *)device;
			return 0;
	    } else {
	        return -1;
    	}
  }		
		return -1;  
}

void mClose(JNIEnv *env, jobject cls)
{

	//close(fd);
}


jint mSetv(JNIEnv *env, jobject cls,jint index)
{

	return xxx_device->xxx_setval(xxx_device,index);
}
jint mGetv(JNIEnv *env, jobject cls,jint index)
{

	return xxx_device->xxx_Getval();
}
.....

static const JNINativeMethod methods[] = {
	{"native_open", "()I", (void *)mOpen},
	{"native_close", "()V", (void *)mClose},

	{"native_getVal", "()I", (void *)mGetv},
	{"native_setVal", "(I)I", (void *)mSetv},


};
	

int register_android_server_MyService(JNIEnv *env)
{
    return jniRegisterNativeMethods(env, "com/android/server/MyService",
            methods, NELEM(methods));
}

}

/frameworks/base/services/core/jni/onload.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.
 */

#include "JNIHelp.h"
#include "jni.h"
#include "utils/Log.h"
#include "utils/misc.h"

namespace android {
int register_android_server_AlarmManagerService(JNIEnv* env);
....
//xxxxx add
int register_android_server_MyService(JNIEnv* env);
};

using namespace android;

extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        ALOGE("GetEnv failed!");
        return result;
    }
    ALOG_ASSERT(env, "Could not retrieve the env!");

    register_android_server_PowerManagerService(env);
    ...
//xxxxx add
	register_android_server_MyService(env);
    return JNI_VERSION_1_4;
}

3、HAL

然后就是就是jni调用hal的东西了,说实话hal我就不懂了,这里是我们驱动工程师去编写的,大致如下仅供参考

/hardware/libhardware/include/hardware/myxxx_hal.h

/hardware/libhardware/modules/myxxx/myxxx_hal.c

/hardware/libhardware/modules/myxxx/Android.mk

编译生成.so 或者.a,jni调用

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myxxx.default
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_C_INCLUDES := hardware/libhardware
LOCAL_SRC_FILES := myxxx_hal.c
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_MODULE_TAGS := eng

include $(BUILD_SHARED_LIBRARY)

/hardware/libhardware/modules/Android.mk

hardware_modules := gralloc hwcomposer audio nfc nfc-nci local_time \
	power usbaudio audio_remote_submix camera usbcamera consumerir sensors vibrator \
	tv_input fingerprint input \
# add
    myxxx
include $(call all-named-subdir-makefiles,$(hardware_modules))

hal到硬件控制就是各种厂商做的

这样完整的一套流程就ok了。

从驱动层到framwork再到app api使用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Android应用程序中调用SD卡的vendor hook,通常需要通过JNI来实现。具体步骤如下: 1. 定义JNI接口:在Java层定义一个JNI接口,用于调用SD卡的vendor hook。例如: ```java public class SdVendorHook { static { System.loadLibrary("sd_vendor_hook"); } public static native int sdVendorHook(int arg1, int arg2, ...); } ``` 其中,sdVendorHook方法对应着SD卡的vendor hook,需要传入相应的参数。 2. 实现JNI接口:在JNI的实现中,可以使用Java Native Interface (JNI)来调用内核中的系统调用实现SD卡的vendor hook。例如: ```c #include <jni.h> JNIEXPORT jint JNICALL Java_com_example_myapp_SdVendorHook_sdVendorHook(JNIEnv *env, jclass type, jint arg1, jint arg2, ...) { jint ret = 0; va_list args; // 调用SD卡的vendor hook va_start(args, arg2); ret = syscall(333, arg1, arg2, args); va_end(args); return ret; } ``` 在上述代码中,我们实现了一个名为Java_com_example_myapp_SdVendorHook_sdVendorHook的JNI接口,在其中调用了SD卡的vendor hook。需要注意的是,vendor hook的系统调用号为333,这需要与内核中的实际定义相对应。 3. 编译JNI库并加载到应用程序中:在完成JNI接口实现后,需要将其编译成JNI库,并将其加载到Android应用程序中。这可以通过以下步骤来完成: - 编写JNI代码:将上述JNI接口实现代码保存为名为sd_vendor_hook.c的文件。 - 生成JNI库:使用ndk-build命令编译JNI代码,生成名为libsd_vendor_hook.so的JNI库文件。 - 拷贝JNI库:将生成的JNI库文件拷贝到Android应用程序的libs目录下。 - 加载JNI库:在应用程序的Java代码中调用System.loadLibrary("sd_vendor_hook")来加载JNI库。 需要注意的是,由于vendor hook通常是厂商定制的接口,因此在调用时需要谨慎处理,避免对系统造成不必要的影响。同时,厂商定制的接口可能会因为定制版本的不同而有所差异,因此需要根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值