i.mx6 Android5.1.1 servicemanager本地服务
接在之前的
i.mx6 Android5.1.1 初始化流程之init进程
i.mx6 Android5.1.1 初始化流程之init.rc解析
servicemanager是由init创建的本地服务,是binder的守护进程。
主要用来管理开发者创建的各种Server,并且向Client提供查询Server远程接口的功能。
#名字为servicemanager的服务,可执行文件的路径在/system/bin/servicemanager #属于core类,用户为:system,用户组为:system #critical:如果在几分钟内一直没响应则重启服务 #重启servicemanager需要冲入如下的服务healthd,zygote,media,surfaceflinger,drm service servicemanager /system/bin/servicemanagerclass coreuser system group systemcriticalonrestart restart healthdonrestart restart zygoteonrestart restart mediaonrestart restart surfaceflingeronrestart restart drm
可以得知其路径在/system/bin/servicemanager
查看android.mk
include $(CLEAR_VARS) LOCAL_SHARED_LIBRARIES := liblog libselinux LOCAL_SRC_FILES := service_manager.c binder.c LOCAL_CFLAGS += $(svc_c_flags) LOCAL_MODULE := servicemanager include $(BUILD_EXECUTABLE)
可以得知,就是在service_manager.c
int main(int argc, char **argv) {struct binder_state *bs;//打开binder设备驱动文件,并将Binder设备文件映射到servicemanger进程的地址空间中 bs = binder_open(128*1024);if (!bs) {ALOGE("failed to open binder driver\n");return -1;}//在binder驱动层设置服务管理者角色 if (binder_become_context_manager(bs)) {ALOGE("cannot become context manager (%s)\n", strerror(errno));return -1;}selinux_enabled = is_selinux_enabled();sehandle = selinux_android_service_context_handle();if (selinux_enabled > 0) {if (sehandle == NULL) {ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");abort();}if (getcon(&service_manager_context) != 0) {ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");abort();}}union selinux_callback cb;cb.func_audit = audit_callback;selinux_set_callback(SELINUX_CB_AUDIT, cb);cb.func_log = selinux_log_callback;selinux_set_callback(SELINUX_CB_LOG, cb);//接收到请求后的需要执行的回调函数svcmgr_handle = BINDER_SERVICE_MANAGER;//进入binder.c循环,等待客户请求 binder_loop(bs, svcmgr_handler);return 0; }
struct binder_state *binder_open(size_t mapsize) {。。。//打开设备节点bs->fd = open("/dev/binder", O_RDWR);。。。 //映射bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);。。。 }
再看看直接的那个回调函数
int svcmgr_handler(struct binder_state *bs,struct binder_transaction_data *txn,struct binder_io *msg,struct binder_io *reply) {。。。 switch(txn->code) { case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) { return -1; } //查找相关的服务,如果有,则返回其句柄 handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid); if (!handle) break; bio_put_ref(reply, handle); return 0; case SVC_MGR_ADD_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) { return -1; } handle = bio_get_ref(msg); allow_isolated = bio_get_uint32(msg) ? 1 : 0; //想servicemanager添加服务 if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, txn->sender_pid)) return -1; break; case SVC_MGR_LIST_SERVICES: { uint32_t n = bio_get_uint32(msg); if (!svc_can_list(txn->sender_pid)) { ALOGE("list_service() uid=%d - PERMISSION DENIED\n", txn->sender_euid); return -1; } si = svclist; while ((n-- > 0) && si) si = si->next; if (si) { bio_put_string16(reply, si->name); return 0; } return -1; } default: ALOGE("unknown code %d\n", txn->code); return -1; } bio_put_uint32(reply, 0); return 0; }
void binder_loop(struct binder_state *bs, binder_handler func) {int res;struct binder_write_read bwr;uint32_t readbuf[32];bwr.write_size = 0;bwr.write_consumed = 0;bwr.write_buffer = 0;readbuf[0] = BC_ENTER_LOOPER;binder_write(bs, readbuf, sizeof(uint32_t));for (;;) {bwr.read_size = sizeof(readbuf);bwr.read_consumed = 0;bwr.read_buffer = (uintptr_t) readbuf;//读取binder节点数据 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);if (res < 0) {ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));break;}//解析 res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);if (res == 0) {ALOGE("binder_loop: unexpected reply?!\n");break;}if (res < 0) {ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));break;}} }
int binder_parse(struct binder_state *bs, struct binder_io *bio,uintptr_t ptr, size_t size, binder_handler func) {。。。switch(cmd) {。。。binder_dump_txn(txn);if (func) {unsigned rdata[256/4];struct binder_io msg;struct binder_io reply;int res;bio_init(&reply, rdata, sizeof(rdata), 4);bio_init_from_txn(&msg, txn); //注意:这个是之前我们传进来的回调函数res = func(bs, txn, &msg, &reply);binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);}ptr += sizeof(*txn);break;} 。。。default:ALOGE("parse: OOPS %d\n", cmd);return -1;}}return r; }
小结:
1.申请一段内存,打开设备节点/dev/binder,同时将内存映射到内核中用来给binder使用
2.将自己设置为服务管理者
3.通过binder接口循环读取查看是否有数据,当有数据传来时,调用回调函数添加服务,或者查询服务
转载于:https://www.cnblogs.com/maogefff/p/7661289.html
i.mx6 Android5.1.1 servicemanager本地服务相关推荐
- Android Binder机制:编写自己的本地服务
原址 前面几篇博客中系统地介绍了本地服务的注册.检索以及使用过程.这篇博客我们将完成一个属于自己的本地服务:AllenService. 由前面的学习知道,要完成一个自己的本地服务,需要有IAllenS ...
- 工作流编程循序渐进(9:使用本地服务在宿主和工作流之间通信)
工作流编程循序渐进(9:使用本地服务在宿主和工作流之间通信) 作者 朱先忠 [摘要] 在本篇中,首先详细分析本地服务有关概念,探讨本地服务在工作流运行时.工作流实例及工作流宿主间的地位及 ...
- centos7 搭建本地git_本地服务调用K8S环境中的SpringCloud微服务实战
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:原创文章分类汇总及配套源码,涉及Java.Docker.K8S.Devops等 下图是典型的微 ...
- windows的服务中的登录身份本地系统账户、本地服务账户和网络服务账户修改
以一个redis服务为例: 一个redis注册服务后一般是网络服务账户,但是当系统不存在网络服务账户时,就会导致redis服务无法正常启动.接下来修改redis服务的登录身份. cmd下输入如下命令: ...
- Android Service学习之本地服务
Service是在一段不定的时间运行在后台,不和用户交互应用组件.每个Service必须在manifest中 通过<service>来声明.可以通过contect.startservice ...
- 增加 oracle服务名,oracle本地服务名配置说明
本地oracle客户端连接远程oracle数据库服务器配置说明如下: 1.找到本地oracle客户端安装目录,如:%path%\Oracle 2.再找配置文件tnsnames.ora,其目录为 %pa ...
- WF(9):本地服务之事件处理
一:先来介绍两个活动 EventDrivenActivity和 ListenActivity. EventDrivenActivity是一个等侍事件触发的容器,EventDrivenActivity第 ...
- 如何给Android应用创建本地服务
Android系统给应用提供了两种类型的服务:启动型本地服务和绑定型本地服务,这两种服务的详细信息请参考"Android Service开发指南" Android Service开 ...
- mac如何将本地服务暴露到外网?
在做微信公众号开发时,需要将本地服务暴露到外网,除了ngrok外,还有什么方法呢? 假设本地有个test文件夹,那么如何才能使别人通过浏览器访问到你的文件夹?接下来介绍另一个方法:localtunne ...
最新文章
- 下次迟到的借口有了!牛津大学发现时钟越准确,产生的熵越高
- qt combox 向上弹出_一睹芳容!人类首次拍到活的公羊角乌贼 手臂和触须向上飞速穿过水柱...
- java将数据封装为树结构_JAVA代码实现多级树结构封装对象
- Android布局中涉及的一些属性
- CAN总线的初步认识
- 灯塔的出现给那些有想法,有能力而又缺乏资金的社区人士提供了一条途径
- MFC的六大关键技术
- Could not autowire. No beans of 'xxxx' type found的错误提示
- java,类的构造方法
- maven setting文件_只用一招,让你Maven依赖下载速度快如闪电
- 计算机建模报告,计算机三维建模及分析实验报告单.doc
- 尴尬又暖心!学生知乎上提问导师人品如何,没想到导师亲自回答了...
- 虹膜识别与虹膜定位(续)算法实现
- 《推荐系统实践》算法纯享(附代码链接)(四)—— UGC推荐篇
- 《商务与经济统计》学习笔记(三)
- 世界各国国家代码简称
- python 地震数据可视化
- php文章下一页,php获取文章上一页与下一页的方法,_PHP教程
- 湖南计算机应用技术专科学校排名,湖南所有职业技术学院排名
- torch.mul torch.bmm