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.h

2 directories, 4 files

1.创建文件夹 customcamera 以及两个子文件夹 customcamera 和 libcustomcamera 

首先创建  CustomCamera.cpp 和  CustomCamera.h 因为是简单的Demo 代码并未写复杂

-----CustomCamera.h 内容如下:

#ifndef ANDROID_GUILH_ADD_SERVICE_H
#define ANDROID_GUILH_ADD_SERVICE_H
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/threads.h>
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 <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
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_camera
		ALOGW("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

代码写到这一步的时候可以现在本文件夹下简历一个makefile文件 测试当前写的CustomCamera.cpp 写的是不是正确,也可以后期测试,这里就进行后期测试.

之后在customcamera 文件夹下创建 customcamera.cpp 和 Android.mk 文件.

------customcamera.cpp内容如下

#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include <private/android_filesystem_config.h>
#include "../libcustomcamera/CustomCamera.h"

using namespace android;

int main(int argc, char** argv)

{

	sp<ProcessState> proc(ProcessState::self());
	sp<IServiceManager> sm = defaultServiceManager();//取得 ServiceManager
	ALOGW("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-variable

LOCAL_CONLYFLAGS := -std=c11

LOCAL_SHARED_LIBRARIES := libcutils \
                libsysutils \
        libutils \
        libbinder \
        libui \
        libgui \
        liblog

LOCAL_LDLIBS := -llog

LOCAL_MODULE := custom_camera

LOCAL_MODULE_TAGS := optional

LOCAL_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 带到系统里面.

2.如果我们是提前编译好的 custom_camera 将custom_camera放到一个文件下, 在系统的对应的mk中添加拷贝代码.

比如我的是高通的代码 添加 路径为 device/qcom/msmxxx/msmxxx.mk

这句话的意识就是标示 如果编译系统的时候 将这个文件 拷贝到 out/target/product/msmxxxx/system/bin/custom_camera

PRODUCT_COPY_FILES += \
    out/target/product/msm8953_64/system/bin/custom_camera:system/bin/custom_camera

四.启动服务

添加启动服务的代码 文件路径为 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
     chmod 0440 /sys/devices/soc.0/78b7000.i2c/i2c-3/3-0020/input/input0/secure_touch
     chmod 0660 /sys/devices/soc.0/78b8000.i2c/i2c-4/4-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("guilh.add");// 取得服务

                        Parcel data = Parcel.obtain();

                        Parcel reply = Parcel.obtain();

                        if(binder == null)

                                Log.d(TAG,"failed to get service");

                        data.writeInt(Process.myPid());// 固定操作

                        data.writeInt(100);// 传入参数

                        binder.transact(0, data, reply, 0);// 执行远程调用

                        Log.d(TAG,"result="+reply.readInt());// 验证结果

                }catch(Exception e){

                         Log.d(TAG,e.toString());

                }

六.添加selinux权限

Android 7.1 添加一个进程间通讯的系统服务(java层) 文章的后半部分有介绍,这里就不再过多赘述

主要设计如下几个文件


#主要是修改 neverallow 内容
#-mcu_service
system/sepolicy/domain.te


#/system/bin/custom_camera  u:object_r:custom_camera_service_exec:s0
system/sepolicy/file_contexts


# custom_camera               u:custom_camera_service_exec:s0
system/sepolicy/custom_camera.te # 拷贝别的te修改名字就行


# custom_camera               u:object_r:custom_camera_service_service:s0
system/sepolicy/service_contexts #  与 file_contexts 相对应
发布了26 篇原创文章 · 获赞 14 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ChaoLi_Chen/article/details/105615126
今日推荐