Android 理解frameworks services jni hardware kernel 整个控制过程实例包括回调

一、这个例子的实现的功能是,app控制power pin和control pin,可以read feedback pin的电平,如果feedback pin的电平有变化,会触发中断,底层把这个中断信息通过一系列回调和侦听发送到app。

通过这个简单的实例可以了解frameworks services jni hardware kernel整个流程,里面涉及到回调和侦听还是需要花费很多精力去理解和调试。

二、kernel 驱动\kernel\drivers\char\moneybox.c,获取中断,控制gpio,提供杂项设备节点 /dev/moneybox以及下面3个控制节点

       /sys/devices/platform/moneybox/enpower

       /sys/devices/platform/moneybox/control

       /sys/devices/platform/moneybox/feedback

三、hardware 主要代码下面的代码

      hardware/libhardware/include/hardware/moneybox.hhardware/libhardware/modules/Android.mkhardware/libhardware/modules/moneybox/Android.mkhardware/libhardware/modules/moneybox/moneybox.cpp

3.1 moneybox.cpp代码

3.2 moneybox.h代码

#ifndef ANDROID_FREG_INTERFACE_H
#define ANDROID_FREG_INTERFACE_H#include <hardware/hardware.h>__BEGIN_DECLS/*** The id of this module*/
#define MONEYBOX_HARDWARE_MODULE_ID "moneybox"/*** The id of this device*/
#define MONEYBOX_HARDWARE_DEVICE_ID "moneybox"struct moneybox_module_t {struct hw_module_t common;
};/* Callback function type */
typedef void (*moneybox_notify_t)(int m,int n);struct moneybox_device_t {struct hw_device_t common;int fd;moneybox_notify_t notify;int (*set_val)(struct moneybox_device_t* dev, int val);int (*set_enable_power)(struct moneybox_device_t* dev, int val);int (*set_control_val)(struct moneybox_device_t* dev, int val);int (*get_feedback_val)(struct moneybox_device_t* dev, int* val);int (*set_notify)(struct moneybox_device_t *dev, moneybox_notify_t notify);
};__END_DECLS#endif

四、JNI代码frameworks/base/services/core/jni/com_android_server_MoneyboxService.cpp

#define LOG_TAG "MoneyboxServiceJNI"#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/moneybox.h>
#include <utils/Looper.h>
#include <android_os_MessageQueue.h>#include <stdio.h>static jobject mCallbacksObj = NULL;
static jmethodID javaCallback;JNIEnv* m_env;
jobject mobj;
jclass jSdkClass;jobject g_jobj;  //全局对象namespace android
{static void moneybox_setVal(JNIEnv* env, jobject clazz, jint ptr, jint value) {moneybox_device_t* device = (moneybox_device_t*)ptr;if(!device) {ALOGE("Device moneybox is not open.");return;}  int val = value;ALOGI("Set value %d to device moneybox.", val);device->set_val(device, val);}
static void moneybox_set_enable_power(JNIEnv* env, jobject clazz, jint ptr, jint value) {moneybox_device_t* device = (moneybox_device_t*)ptr;if(!device) {ALOGE("Device moneybox is not open.");return;} int val = value;device->set_enable_power(device, val);ALOGI("Set value %d to device moneybox.", val);}static void moneybox_set_control_val(JNIEnv* env, jobject clazz, jint ptr, jint value) {int val = value;moneybox_device_t* device = (moneybox_device_t*)ptr;if(!device) {ALOGE("Device moneybox is not open.");return;}         device->set_control_val(device, val);ALOGI("Set value %d to device moneybox.", val);}static inline int moneybox_device_open(const hw_module_t* module, struct moneybox_device_t** device) {return module->methods->open(module, MONEYBOX_HARDWARE_DEVICE_ID, (struct hw_device_t**)device);}
// Called by the HAL to notify us of moneybox eventsstatic void hal_notify_callback(int m,int n) {JNIEnv* env = AndroidRuntime::getJNIEnv();if (!mCallbacksObj)return;jclass clz = env->GetObjectClass(mCallbacksObj);jint   ret  =  env->CallStaticIntMethod(clz, javaCallback,(jint)m,(jint)n);ALOGI("hal_notify_callback ,m=%d,n=%d,ret=%d.",m,n,ret);}static jint moneybox_get_feedback_val(JNIEnv* env, jobject clazz, jint ptr) {int val = 0;moneybox_device_t* device = (moneybox_device_t*)ptr;if(!device) {ALOGE("Device moneybox is not open.");return 0;}device->get_feedback_val(device, &val);ALOGI("Get Value %d from device moneybox....", val);#if 0 if (!mCallbacksObj)mCallbacksObj = env->NewGlobalRef(clazz);jclass clz = env->GetObjectClass(mCallbacksObj);//jint ret  = env->CallIntMethod(mCallbacksObj, javaCallback,(jint)val,(jint)val);jint ret  = env->CallStaticIntMethod(clz, javaCallback,(jint)val,(jint)val);if (env->ExceptionCheck()) {ALOGE("An exception was thrown by callback");env->ExceptionClear();}ALOGI(" CallIntMethod mCallbacksObj env ret=%d",ret);#endif    return val;}static jint moneybox_init(JNIEnv* env, jobject clazz) {int err;moneybox_module_t* module;moneybox_device_t* device;ALOGI("Initializing HAL stub moneybox......");if(hw_get_module(MONEYBOX_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) {ALOGI("Device moneybox found.");if(moneybox_device_open(&(module->common), &device) == 0) {ALOGI("Device moneybox is Opened.");err=device->set_notify(device, hal_notify_callback);if (err < 0) {ALOGE("Failed in call to set_notify(), err=%d", err);}elseALOGI("Call to set_notify successfully!");if (!mCallbacksObj)mCallbacksObj = env->NewGlobalRef(clazz);ALOGI("moneybox_device_open   successfully!");return (jint)device;}ALOGE("Failed to open device moneybox.");return 0;}ALOGE("Failed to get HAL stub moneybox.");return 0;        }
static void moneybox_class_init_native(JNIEnv* env, jclass clazz) {ALOGE("moneybox_class_init_native   GetMethodID  moneybox_callback");//javaCallback = env->GetMethodID(clazz, "moneybox_callback", "(II)I");javaCallback = env->GetStaticMethodID(clazz, "moneybox_callback", "(II)I");
}static const JNINativeMethod method_table[] = {{"class_init_native", "()V", (void *)moneybox_class_init_native},{"init_native", "()I", (void*)moneybox_init},{"setVal_native", "(II)V", (void*)moneybox_setVal},{"set_enable_power_native", "(II)V", (void*)moneybox_set_enable_power},{"set_control_val_native", "(II)V", (void*)moneybox_set_control_val},{"get_feedback_val_native", "(I)I", (void*)moneybox_get_feedback_val},
};int register_android_server_MoneyboxService(JNIEnv *env) {int res = jniRegisterNativeMethods(env, "com/android/server/MoneyboxService", method_table, NELEM(method_table));/*jclass clazz;clazz=env->FindClass("com/android/server/MoneyboxService");javaCallback = env->GetMethodID(clazz, "moneybox_callback", "(II)I");*/ALOGI("register_android_server_MoneyboxService");return res;
}};

五、frameworks/base/services/core/jni/onload.cpp注册jni

int register_android_server_MoneyboxService(JNIEnv* env);

六、添加服务文件frameworks/base/services/core/java/com/android/server/MoneyboxService.java

七,添加manager文件, frameworks/base/core/java/android/os/SystemMoneybox.java ,提供api个app

八、添加服务frameworks/base/services/java/com/android/server/SystemServer.java

     try {traceBeginAndSlog("Moneybox Service");ServiceManager.addService("moneybox", new MoneyboxService(context));} catch (Throwable e) {Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);}

九、注册服务  frameworks/base/core/java/android/app/SystemServiceRegistry.java

     registerService(Context.MONEYBOX_SERVICE, SystemMoneybox.class,new CachedServiceFetcher<SystemMoneybox>() {@Overridepublic SystemMoneybox createService(ContextImpl ctx) {//return new SystemMoneybox(ctx);//ctx.mMainThread.getHandler().getLooper()return new SystemMoneybox(ctx,ctx.mMainThread.getHandler().getLooper());}});

十、添加frameworks/base/core/java/android/os/IMoneyboxService.aidl进行跨进行binder通信

package android.os;import android.os.IMoneyboxTListener;interface IMoneyboxService {void setVal(int val);void set_enable_power(int val);void set_control_val(int val);int  get_feedback_val();void registerListener(IMoneyboxTListener listener);
}

十一、添加frameworks/base/core/java/android/os/IMoneyboxTListener.aidl用于回调binder通信

package android.os;import android.os.Bundle;oneway interface IMoneyboxTListener
{void onMoneyboxChanged(int i);
}

十二、添加frameworks/base/location/java/android/location/MoneyboxListener.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 android.location;import android.os.Bundle;/*** Used for receiving notifications from the LocationManager when* the location has changed. These methods are called if the* LocationListener has been registered with the location manager service* using the {@link LocationManager#requestLocationUpdates(String, long, float, LocationListener)}* method.** <div class="special reference">* <h3>Developer Guides</h3>* <p>For more information about identifying user location, read the* <a href="{@docRoot}guide/topics/location/obtaining-user-location.html">Obtaining User* Location</a> developer guide.</p>* </div>*/
public interface MoneyboxListener {void onMoneyboxChanged(int i);
}

十三、frameworks/base/Android.mk添加下面内容

core/java/android/os/IMoneyboxService.aidl \
core/java/android/os/IMoneyboxTListener.aidl \

十四、APP demo,app通过下面两种方法调用系统服务。

IMoneyboxService.Stub.asInterface( ServiceManager.getService("moneybox"));

或者

(SystemMoneybox) getSystemService("moneybox");

十五、make update-api更新api,mmm frameworks/base/services/、mmm frameworks/base/编译出framework.jar、services.jar和libandroid_servers.so(jni),push到机器运行测试

15.1、执行service list查看该服务是否已经start。

15.2、确认是否已经生成杂项设备节点和平台总线控制node。

xxx:/ # ls -l /dev/moneybox
crwxrwxrwx 1 root root 10,  60 2021-04-27 00:26 /dev/moneybox
xxx:/ # ls /sys/devices/platform/moneybox/
control driver driver_override enpower feedback modalias of_node power subsystem uevent
xxx:/ #

15.3、运行demo app

15.3、点击demo里面的button调用framework接口,然后通过servies,jni、hardware、kernel控制gpio,然后feedback gpio电平有变化的时候会通过一系列回调传数据到app,看下面的log,

所有的通路都是测试ok。

十六、整个过程涉及到下面的文件。

DEMO APP代码在Moneyboxapp目录下,用mmm进行编译
A  packages/apps/Moneyboxapp/Android.mk
A  packages/apps/Moneyboxapp/AndroidManifest.xml
A  packages/apps/Moneyboxapp/res/drawable/icon.png
A  packages/apps/Moneyboxapp/res/layout/main.xml
A  packages/apps/Moneyboxapp/res/values/strings.xml
A  packages/apps/Moneyboxapp/src/giada/ibc/moneybox/Moneybox.javaFramework涉及到的代码:
M  device/rockchip/rk3288/device.mk
M  frameworks/base/Android.mk
M  frameworks/base/core/java/android/app/SystemServiceRegistry.java
M  frameworks/base/core/java/android/content/Context.java
A  frameworks/base/core/java/android/os/IMoneyboxService.aidl
A  frameworks/base/core/java/android/os/IMoneyboxTListener.aidl
A  frameworks/base/core/java/android/os/SystemMoneybox.java
A  frameworks/base/location/java/android/location/MoneyboxListener.java
A  frameworks/base/services/core/java/com/android/server/MoneyboxService.java
M  frameworks/base/services/core/jni/Android.mk
A  frameworks/base/services/core/jni/com_android_server_MoneyboxService.cpp
M  frameworks/base/services/core/jni/onload.cpp
M  frameworks/base/services/java/com/android/server/SystemServer.javahardware的代码:
A  hardware/libhardware/include/hardware/moneybox.h
M  hardware/libhardware/modules/Android.mk
A  hardware/libhardware/modules/moneybox/Android.mk
A  hardware/libhardware/modules/moneybox/moneybox.cpp底层驱动涉及到的代码:
M  device/rockchip/common/init.connectivity.rc
M  kernel/arch/arm/boot/dts/rk3288-giada-jhs66l-act8846.dts
M  kernel/drivers/char/Makefile
A  kernel/drivers/char/moneybox.c

十七、源码下载路径 frameworks_services_jni_hardware_kernel.zip-Linux文档类资源-CSDN下载 包含所有的文件。

十八、饮水思源,参考文章:

1、android 创建一个实时监听的系统Service

android 创建一个实时监听的系统Service_lz强的博客-CSDN博客_android 监听service

2、安卓硬件服务实例:手把手教你如何从驱动到应用添加硬件服务

安卓硬件服务实例:手把手教你如何从驱动到应用添加硬件服务_kavin.zhu的博客-CSDN博客_安卓硬件驱动

3、Android Hal层回调APP应用接口

Android Hal层回调APP应用接口_yujd的博客-CSDN博客

4、Android硬件服务框架实例之Vibrator(驱动到应用)

Android硬件服务框架实例之Vibrator(驱动到应用)_kavin.zhu的博客-CSDN博客_android振动代码

5、https://www.jianshu.com/p/0f46a95d576f (Android 添加一个系统服务的完整流程(SystemService))

​​​​​​​

2021-04-27 Android 理解frameworks services jni hardware kernel 整个控制过程实例包括回调相关推荐

  1. Russ Cox:这不是Go项目的标准布局 | Gopher Daily (2021.04.28) ʕ◔ϖ◔ʔ

    每日一谚:Profile before you decide something is performance critical. Go技术生态 Go web开发的当前状态 - https://tno ...

  2. I.MX6 Android frameworks services 文件架构

    /******************************************************************************** I.MX6 Android fram ...

  3. ubuntu-18.04.4 Android系统源码TP1A(Android 13)下载及编译

    继上一篇博客介绍了VMware Workstation15 配置ubuntu-18.04.4,这篇主要介绍安装后环境搭建,Android源码的下载与编译.小编当前下载的是当前最新的代码,是主干分支代码 ...

  4. [2021.8.18]深入理解PackageManagerService

    原文链接:https://blog.csdn.net/Innost/article/details/47253179 本章主要内容: 详细分析PackageManagerService 1  概述 P ...

  5. android studio 单步调试jni,android studio实现Jni单步调试-标准配置教程

    本文主要介绍在android studio下实现jni单步调试时,所需要的配置及其步骤,这些也是本人经过几天折腾慢慢实现的,先提供给大家做参考: 1,配置是在mac下android studio实现的 ...

  6. android 中 Proguard 和JNI 相关

    在Android项目中用到JNI,当用了proguard后,发现native方法找不到很多变量,原来是被produard优化掉了.所以,在JNI应用中该慎用progurad啊. 解决办法: 1.在An ...

  7. [2021.1.27多校省选模拟10]染色(min-max容斥/二项式反演)

    [2021.1.27多校省选模拟10]染色 突然发现我对概率期望的理解不是很好... 部分分1:可以直接进行状压dp,然后按照题意模拟即可. 部分分2:首先可以发现这个问题是min_max容斥形式,然 ...

  8. Android Studio1.4.x JNI开发基础-基本环境配置

    从Eclipse时代到Android Studio普及,开发工具越来越好用.早些时候还需要安装Cygwin工具,从Android Studio1.3以后,在Android 环境开发JNI程序搭建开发环 ...

  9. WSL Ubuntu 20.04下Android源码编译与导入Android Studio

    源码下载见前文:WSL Ubuntu 20.04下Android源码下载 idegen 模块编译 在development/tools/idegen/README下可以看到关于 idegen 工具的相 ...

最新文章

  1. AI检测制造“零缺陷”
  2. linux命令之创建符号连接-ln
  3. 3d点击_gooood合辑:3D打印 | 精选全部3D打印案例
  4. JavaScript学习笔记04【高级——DOM和事件的简单学习、BOM对象】
  5. set 与 map 的第一次尝试
  6. .Net Core应用框架Util介绍(二)
  7. python3.8安装xlwings出错_Python xlwings模块简单使用
  8. java注释 param_@Param注解的用法解析
  9. (转)Spring Boot 2 (五):Docker Compose + Spring Boot + Nginx + Mysql 实践
  10. github 手机号码归属地信息库、手机号归属地查询
  11. ApiPost测试接口获取不到session
  12. 【Unity】ET框架学习笔记
  13. python fundamental structure_Data Structures and Algorithms in Python
  14. Lambda表达式----“进化论”
  15. c语言字母字符参与运算,c语言字符串可以参加运算吗?
  16. 主动提交sitemap让谷歌、雅虎、MSN统统收录你的网站、博客
  17. 华为云服务器 共享文件夹在哪个文件夹,用户数据安全存储 华为云空间这些功能大显身手...
  18. Linux 网络驱动 phy 读写寄存器调试方法
  19. Python :18Python计算器
  20. 这样一首歌,让人泪流满面

热门文章

  1. 如何生成带标高的西安80坐标系等高线
  2. Scipy库(win下安装)
  3. Java --- 线程同步和异步的区别
  4. 个人博客处理——页面处理
  5. Kafka Broker 基本架构二
  6. kubernetes二进制安装
  7. PLA,FPGA 简介
  8. 研发新人如何快速熟悉新项目和业务
  9. SQL Server Management Studio管理数据库
  10. Distiller:神经网络压缩研究框架