作者:vfh1150403 | 来源:互联网 | 2023-09-11 06:24
servicemanager是一个用于查询其他binder服务的特殊binder服务。在init解析init.rc中启动的,是一个c程序,在路径frameworksativecmd
service manager是一个用于查询其他binder服务的特殊binder服务。
在init解析init.rc中启动的,是一个c程序,在路径/frameworks/native/cmds/servicemanager下,由两个文件构成service_manager.c和binder.c #init.rc service servicemanager /system/bin/servicemanager class core user system group system critical #当servicemanager由于致命错误导致重启,其他系统服务zygote,media,surfaceflinger,drm也会重启 onrestart restart zygote onrestart restart media onrestart restart surfaceflinger onrestart restart drm
工作流程 打开binder设备,做相关初始化 //service_manager.c //main() struct binder_state *bs;//该结构体包含binder相关信息 bs=binder_open(128*1024); //binder.c //binder_open() struct binder_state *bs; bs = malloc(sizeof(*bs)); bs->fd = open("/dev/binder",O_RDWR)//打开binder驱动 bs->mapsize = mapsize; bs->mapped = mmap(NULL, mapsize, PROT_READ,MAP_PRIVATE,bs->fd,0);//mmap用于将设备(bs->fd=/dev/binder)中指定的内存(0=起始地址)映射到进程空间(bs->mapped)中 return bs;
将自己设置为binder大管家 //service_manager.c //main() binder_become_context_manager(bs); //binder_become_context_manager() return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR,0);//ioctl向binder驱动发送命BINDER_SET_CONTEXT_MGR
进入处理循环,开始等待和处理客户端请求 //service_manager.c //main() binder_loop(bs,BINDER_SERVICE_MANAGER) //binder_loop() 1. 从binder驱动读取消息==ioctl 2. 处理消息==binder_parse 3. 不断循环
例子 service
#include #include #include #include #include #define LOG_TAG "binderserver" using namespace android; class MyBinderService : public BBinder{ //override status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { printf("MyBinderService onTransact code = %d\n", code); if(code == 123) { int readInt = 0; readInt = data.readInt32(); printf("MyBinderService onTransact readInt = %d\n", readInt); reply->writeInt32(234); } printf("return NO_ERROR\n"); return NO_ERROR; } }; int main(int argc, char** argv) { sp serverBinder = new MyBinderService(); defaultServiceManager()->addService(String16("mybindertag"), serverBinder); printf("main addService \n"); sp proc(ProcessState::self()); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); printf("never return!!! \n"); return 0; }c
#######################################Android.mk LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) #需要编译的cpp文件 LOCAL_SRC_FILES:= mybinderserver.cpp LOCAL_C_INCLUDES := \ external/skia/include/core \ bionic \ external/stlport/stlport #编译为可执行文件 LOCAL_MODULE:= mybinderserver LOCAL_MODULE_TAGS := optional #添加依赖库一定要有libbinder LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ libbinder \ libgui \ libskia \ libui include $(BUILD_EXECUTABLE)
client
#include #include #include #include #include #define LOG_TAG "binderclient" using namespace android; int main(int argc, char** argv) { sp sm = defaultServiceManager(); //向servicemanager查询id为mybindertag的binger服务器 sp binder = sm->checkService(String16("mybindertag")); if (binder == 0) { printf("service is not found !\n"); return 0; } else { //获取service sp binder = defaultServiceManager()->getService(String16("mybindertag")); } //业务相关 while(1) { Parcel data, reply; int transCode = 0; int writeInt = 0; int replyInt = 0; printf("please input transCode : \n"); scanf("%d", &transCode); getchar(); if(123 == transCode) { printf("please input int you need transfer: \n"); scanf("%d", &writeInt); getchar(); data.writeInt32(writeInt); } //使用binder的transact方法来传递 binder->transact(transCode, data, &reply); replyInt = reply.readInt32(); printf("get reply data = %d\n", replyInt); } return 0; }
#######################################Android.mk LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) #需要编译的cpp文件 LOCAL_SRC_FILES:= mybinderclient.cpp LOCAL_C_INCLUDES := \ external/skia/include/core \ bionic \ external/stlport/stlport #编译为可执行文件 LOCAL_MODULE:= mybinderclient #LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := optional #添加依赖库一定要有libbinder LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ libbinder \ libgui \ libskia \ libui include $(BUILD_EXECUTABLE)
编译测试
在 frameworks\base\cmds 创建相应的文件夹mybinderserver,把Android.mk和mybinderserver.cpp拷贝进去编译的时候
执行. build/envsetup.sh
lunch 选择对应的版本
mmm frameworks/base/cmds/mybinderserver/
adb root
adb remount
adb push out/target/product/rk3368/system/bin/mybinderserver system/bin
同理mybinderclient 也是这样操作。