Android(安卓)7.1添加一个 系统底层服务
受疫情影响,自己工作目前又比较忙,很长时间没有更细博客了,最近看了一下底层服务,尝试着添加了一个底层服务,之前写过一个文章是 Android在java层添加服务进行通讯,对Java层服务感兴趣的同学可以去看一下
Android 7.1 添加一个进程间通讯的系统服务(java层)
本次添加一个底层服务,目的是为了应用程序可以获取此服务 与 底层服务和外部设备进行通讯 .
分为大概几个步骤
1.添加文件
2.编译文件
3.将文件打到ROM中
4.添加sepolicy权限
5.测试权限
一:添加文件
本次涉及的文件如下图所示:
frameworks/base$ tree customcamera 显示文件夹结构customcamera├── customcamera //编写可执行文件 │ ├── Android.mk│ └── customcamera.cpp└── libcustomcamera //服务的具体实现类 ├── CustomCamera.cpp └── CustomCamera.h2 directories, 4 files
1.创建文件夹 customcamera 以及两个子文件夹 customcamera 和 libcustomcamera
首先在 libcustomcamera文件夹下创建 CustomCamera.cpp 和 CustomCamera.h 因为是简单的Demo 代码写的比较简单.
-----CustomCamera.h 内容如下:
#ifndef ANDROID_GUILH_ADD_SERVICE_H#define ANDROID_GUILH_ADD_SERVICE_H#include #include #include #include namespace android { class CustomCamera: public BBinder{// 从 BBinder 派生,实现本地接口 public: static int instantiate(); CustomCamera(); virtual ~CustomCamera(); virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t); };}; //namespace#endif
------CustomCamera.cpp
#include "CustomCamera.h"#include #include namespace android { static struct sigaction oldact;static pthread_key_t sigbuskey;// 把自己注册到系统中int CustomCamera::instantiate() {ALOGW("CustomCamera instantiate"); int r = defaultServiceManager()->addService(String16("custom_camera"), new CustomCamera());//服务添加到 Binder Driver 中服务名为 custom_cameraALOGW("CustomCamera r = %d/n", r);return r;}// 构造函数CustomCamera::CustomCamera(){ALOGW("CustomCamera created");pthread_key_create(&sigbuskey, NULL);}// 析构函数CustomCamera::~CustomCamera(){pthread_key_delete(sigbuskey);ALOGW("CustomCamera destroyed");}// 这个是服务具体的本地实现,功能实现都应该放在这里面,通过传入执行代码( code ) // 的不同来执行不同的操作,上层隐射为不同的 api 。status_t CustomCamera::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){switch(code) {case 0: {// 根据 code 的不同执行不同的操作pid_t pid = data.readInt32();int num = data.readInt32();num = num + 1000;reply->writeInt32(num);return NO_ERROR;}break;default:return BBinder::onTransact(code, data, reply, flags);}}};//namespace
到这一步可以先在libcustomcamera本文件夹下建立一个makefile文件 测试当前写的CustomCamera.cpp 是否正确,当然也可以后期测试,这里就进行后期测试.
之后在customcamera 文件夹下创建 customcamera.cpp 和 Android.mk 文件.
------customcamera.cpp内容如下
#include #include #include #include #include #include #include #include #include "../libcustomcamera/CustomCamera.h"using namespace android;int main(int argc, char** argv){sp proc(ProcessState::self());sp sm = defaultServiceManager();//取得 ServiceManagerALOGW("CustomCamera ServiceManager: %p", sm.get());CustomCamera::instantiate();//把自己添加到 ServiceManager中ProcessState::self()->startThreadPool();//启动缓冲池IPCThreadState::self()->joinThreadPool();//这里是把服务添加到 Binder闭合循环进程中}
------Android.mk 内容
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES := ../libcustomcamera/CustomCamera.cpp \ customcamera.cpp \LOCAL_CFLAGS := -D__STDC_CONSTANT_MACROS -Wl,-Map=test.map -g -Wno-unused-parameter -Wno-unused-variableLOCAL_CONLYFLAGS := -std=c11LOCAL_SHARED_LIBRARIES := libcutils \ libsysutils \ libutils \ libbinder \ libui \ libgui \ liblogLOCAL_LDLIBS := -llogLOCAL_MODULE := custom_cameraLOCAL_MODULE_TAGS := optionalLOCAL_C_INCLUDES += $(LOCAL_PATH)#编译为可执行文件include $(BUILD_EXECUTABLE)
到此文件编写完毕.
二.编译文件
之后返回到源码根目录 执行如下
~:source build/envsetup.sh ~:lunch XX<需要编译的目标版本>
然后回到 frameworks/base/customcamera/customcamera 文件夹 执行 mm 命令,进行单模块编译.
此时应该会看到如下图所示内容: successfully 编译成功 (因为代码简单也就五六秒钟)
然后到上图对应的目录下去查找可以看到 :custom_camera 已经在存在了 (红色框内)
三. 打到ROM 中
1.因为我们是在framework/base下面创建的文件Android.mk 系统全编译的时候会自动拷贝到 out目录下的 system/bin下
这样打ROM的时候会把编译好的 custom_camera 带到系统ROM里面.
2.如果我们是在外部提前编译好的 custom_camera 将custom_camera放到某一个文件夹下, 在系统的对应的mk中添加拷贝代码.
比如我的是高通的代码 添加 路径为 device/qcom/msmxxx/msmxxx.mk文件,在文件中增加拷贝custom_camera代码如下:
PRODUCT_COPY_FILES += \ <自己存放custom_camera的路径>/custom_camera:system/bin/custom_camera例如如下面的代码就是拷贝custom_camera 到system/文件夹下PRODUCT_COPY_FILES += \ out/target/product/msm8953_64/system/bin/custom_camera:system/bin/custom_camera
这句话的意思就是标示 如果编译系统的时候 将这个文件 拷贝到 out/target/product/msmxxxx/system/bin/custom_camera
四.启动服务
添加启动服务的代码 文件路径为 device/qcom/msmXXX/init.target.rc 其它平台的可能是其它的 .rc 但是逻辑是一样的
先修改权限
#修改权限 增加的代码 chmod 0777 /system/bin/custom_camera #系统代码不必关注 chmod 0660 /sys/devices/soc.0/78b7000.i2c/i2c-3/3-0020/input/input0/secure_touch_enable
增加开机启动服务
#启动我们的服务,开机启动service custom_camera /system/bin/custom_camera class core user root group root oneshot
五.测试服务
//在应用程序中测试服务的代码: private void test(){ try{ IBinder binder = ServiceManager.getService("custom_camera");// 取得服务 Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); if(binder == null) Log.d(TAG,"failed to get custom_camera"); data.writeInt(Process.myPid());// 固定操作 data.writeInt(100);// 传入参数 binder.transact(0, data, reply, 0);// 执行远程调用 Log.d(TAG," custom_camer aresult="+reply.readInt());// 验证结果 }catch(Exception e){ Log.d(TAG,e.toString()); }
六.添加selinux权限
Android 7.1 添加一个进程间通讯的系统服务(java层) 文章的后半部分有介绍,这里就不再过多赘述
主要涉及如下几个文件
#主要是修改 neverallow 内容#-mcu_servicesystem/sepolicy/domain.te#/system/bin/custom_camera u:object_r:custom_camera_service_exec:s0system/sepolicy/file_contexts# custom_camera u:custom_camera_service_exec:s0system/sepolicy/custom_camera.te # 拷贝别的te修改名字就行# custom_camera u:object_r:custom_camera_service_service:s0system/sepolicy/service_contexts # 与 file_contexts 相对应
更多相关文章
- tcping测试服务器TCP端口
- Android中如何做到Service被关闭后又自动启动
- Android中新建的文件在R没有显示对应的文件解决办法总结
- Android学习14--Android应用资源
- android如何让后台服务service不被杀死(设置前台服务)
- H264解码器源码(Android(安卓)1.6 版和QT都可以调用)
- 在电脑端加密的文件,放在android上进行解密,但是出现pad block cor
- 【Android初学者】Eclipse 资源管理器,文件夹功能区讲解
- Android软键盘在清单文件中所有属性解释大全