当前位置: 首页 > news >正文

Android Framework P4 - ServiceManager 进程

ServiceManager 进程

// /system/core/rootdir/init.rc service servicemanager /system/bin/servicemanager class core user system group system critical onrestart restart healthd onrestart restart zygote onrestart restart media onrestart restart surfaceflinger onrestart restart drm
// /frameworks/native/cmds/servicemanager/service_manager.cintmain(intargc,char**argv){structbinder_state*bs;bs=binder_open(128*1024);if(!bs){ALOGE("failed to open binder driver\n");return-1;}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();selinux_status_open(true);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();}}unionselinux_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);binder_loop(bs,svcmgr_handler);return0;}
// /frameworks/native/cmds/servicemanager/binder.cstructbinder_state*binder_open(size_tmapsize){structbinder_state*bs;structbinder_versionvers;bs=malloc(sizeof(*bs));if(!bs){errno=ENOMEM;returnNULL;}bs->fd=open("/dev/binder",O_RDWR);if(bs->fd<0){fprintf(stderr,"binder: cannot open device (%s)\n",strerror(errno));gotofail_open;}if((ioctl(bs->fd,BINDER_VERSION,&vers)==-1)||(vers.protocol_version!=BINDER_CURRENT_PROTOCOL_VERSION)){fprintf(stderr,"binder: kernel driver version (%d) differs from user space version (%d)\n",vers.protocol_version,BINDER_CURRENT_PROTOCOL_VERSION);gotofail_open;}bs->mapsize=mapsize;bs->mapped=mmap(NULL,mapsize,PROT_READ,MAP_PRIVATE,bs->fd,0);if(bs->mapped==MAP_FAILED){fprintf(stderr,"binder: cannot map device (%s)\n",strerror(errno));gotofail_map;}returnbs;fail_map:close(bs->fd);fail_open:free(bs);returnNULL;}
// /frameworks/native/cmds/servicemanager/binder.cintbinder_become_context_manager(structbinder_state*bs){returnioctl(bs->fd,BINDER_SET_CONTEXT_MGR,0);}
// /frameworks/native/cmds/servicemanager/binder.cvoidbinder_loop(structbinder_state*bs,binder_handler func){intres;structbinder_write_readbwr;uint32_treadbuf[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;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;}}}
// /frameworks/native/cmds/servicemanager/binder.cintbinder_parse(structbinder_state*bs,structbinder_io*bio,uintptr_tptr,size_tsize,binder_handler func){intr=1;uintptr_tend=ptr+(uintptr_t)size;while(ptr<end){uint32_tcmd=*(uint32_t*)ptr;ptr+=sizeof(uint32_t);#ifTRACEfprintf(stderr,"%s:\n",cmd_name(cmd));#endifswitch(cmd){caseBR_NOOP:break;caseBR_TRANSACTION_COMPLETE:break;caseBR_INCREFS:caseBR_ACQUIRE:caseBR_RELEASE:caseBR_DECREFS:#ifTRACEfprintf(stderr," %p, %p\n",(void*)ptr,(void*)(ptr+sizeof(void*)));#endifptr+=sizeof(structbinder_ptr_cookie);break;caseBR_TRANSACTION:{structbinder_transaction_data*txn=(structbinder_transaction_data*)ptr;if((end-ptr)<sizeof(*txn)){ALOGE("parse: txn too small!\n");return-1;}binder_dump_txn(txn);if(func){unsignedrdata[256/4];structbinder_iomsg;structbinder_ioreply;intres;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;}caseBR_REPLY:{structbinder_transaction_data*txn=(structbinder_transaction_data*)ptr;if((end-ptr)<sizeof(*txn)){ALOGE("parse: reply too small!\n");return-1;}binder_dump_txn(txn);if(bio){bio_init_from_txn(bio,txn);bio=0;}else{/* todo FREE BUFFER */}ptr+=sizeof(*txn);r=0;break;}caseBR_DEAD_BINDER:{structbinder_death*death=(structbinder_death*)(uintptr_t)*(binder_uintptr_t*)ptr;ptr+=sizeof(binder_uintptr_t);death->func(bs,death->ptr);break;}caseBR_FAILED_REPLY:r=-1;break;caseBR_DEAD_REPLY:r=-1;break;default:ALOGE("parse: OOPS %d\n",cmd);return-1;}}returnr;}
// /frameworks/native/cmds/servicemanager/service_manager.cintsvcmgr_handler(structbinder_state*bs,structbinder_transaction_data*txn,structbinder_io*msg,structbinder_io*reply){structsvcinfo*si;uint16_t*s;size_tlen;uint32_thandle;uint32_tstrict_policy;intallow_isolated;//ALOGI("target=%p code=%d pid=%d uid=%d\n",// (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);if(txn->target.ptr!=BINDER_SERVICE_MANAGER)return-1;if(txn->code==PING_TRANSACTION)return0;// Equivalent to Parcel::enforceInterface(), reading the RPC// header with the strict mode policy mask and the interface name.// Note that we ignore the strict_policy and don't propagate it// further (since we do no outbound RPCs anyway).strict_policy=bio_get_uint32(msg);s=bio_get_string16(msg,&len);if(s==NULL){return-1;}if((len!=(sizeof(svcmgr_id)/2))||memcmp(svcmgr_id,s,sizeof(svcmgr_id))){fprintf(stderr,"invalid id %s\n",str8(s,len));return-1;}if(sehandle&&selinux_status_updated()>0){structselabel_handle*tmp_sehandle=selinux_android_service_context_handle();if(tmp_sehandle){selabel_close(sehandle);sehandle=tmp_sehandle;}}switch(txn->code){caseSVC_MGR_GET_SERVICE:caseSVC_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);return0;caseSVC_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;if(do_add_service(bs,s,len,handle,txn->sender_euid,allow_isolated,txn->sender_pid))return-1;break;caseSVC_MGR_LIST_SERVICES:{uint32_tn=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);return0;}return-1;}default:ALOGE("unknown code %d\n",txn->code);return-1;}bio_put_uint32(reply,0);return0;}
// /frameworks/native/cmds/servicemanager/service_manager.cintdo_add_service(structbinder_state*bs,constuint16_t*s,size_tlen,uint32_thandle,uid_tuid,intallow_isolated,pid_tspid){structsvcinfo*si;//ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle,// allow_isolated ? "allow_isolated" : "!allow_isolated", uid);if(!handle||(len==0)||(len>127))return-1;if(!svc_can_register(s,len,spid)){ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",str8(s,len),handle,uid);return-1;}si=find_svc(s,len);if(si){if(si->handle){ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n",str8(s,len),handle,uid);svcinfo_death(bs,si);}si->handle=handle;}else{si=malloc(sizeof(*si)+(len+1)*sizeof(uint16_t));if(!si){ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n",str8(s,len),handle,uid);return-1;}si->handle=handle;si->len=len;memcpy(si->name,s,(len+1)*sizeof(uint16_t));si->name[len]='\0';si->death.func=(void*)svcinfo_death;si->death.ptr=si;si->allow_isolated=allow_isolated;si->next=svclist;svclist=si;}binder_acquire(bs,handle);binder_link_to_death(bs,handle,&si->death);return0;}
  1. binder_open(128*1024):打开 Binder 驱动

    • open("/dev/binder", O_RDWR):打开/dev/binder

    • 检查驱动版本:ioctl(bs->fd, BINDER_VERSION, &vers)获取驱动版本,vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION对比版本

    • mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0):内存映射

    • return bs:返回句柄

  2. binder_become_context_manager(bs):成为上下文管理器,固定编号 0

  3. binder_loop(bs, svcmgr_handler):进入 Binder 循环,处理所有请求

    • binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func):解析数据

      • switch(cmd):处理业务
http://www.gsyq.cn/news/1383921.html

相关文章:

  • composer require hyperf/filesystem的庖丁解牛
  • 深度学习进阶:自然语言处理|4.1.2 QA|grads 列表与省略号 [...] 详解
  • Vue基础(32)_TodoList案例
  • 5个步骤掌握FanControl:Windows风扇控制终极静音方案
  • SLAM/VIO中的信息矩阵:为什么它是优化问题的‘灵魂’?一个直观的图解指南
  • GIS工程应用记录(AI辅助编程)
  • DS4Windows终极指南:3步让PS手柄在PC上完美运行游戏
  • 嵌入式工程师代码能力综合评估标准
  • 为什么这个免费工具能快速修复你的重要视频文件:完整实战指南
  • ZMJS,把 JavaScript 解释器放进 SAP ABAP 应用服务器之后,很多扩展思路会变得不一样
  • 2026 太原装修公司十佳榜单重磅发布!口碑实力双优,装修选对不踩坑 - 资讯快报
  • 万字详解面试题库 - Agent篇
  • MIMIC-CXR数据集加载实战:用Python从零处理医学影像与报告(附完整代码)
  • oatpp开发环境在linux上的部署
  • 2026广州增城注册公司怎么选?本地老创业者实测5家靠谱财税,避坑不踩雷 - 资讯快报
  • Codex使用API Key授权无法使用插件?
  • 2026广州高企认定机构哪家靠谱?主流代办服务商场景适配测评清单 - 资讯快报
  • CVE编号申请实战指南:从漏洞验证到协同披露
  • 2026年横评10款降AIGC网站:一键锁定高效助手!
  • 夏季血压“正常”了,能停药吗?别让好心办坏事
  • 【python】ImportError: DLL load failed while importing QtWidgets: 找不到指定的程序。重新安装后搞定
  • yolo视频识别 车辆速度估计识别 yolo11视频实时速度测量与测速估计
  • Amphenol ICC ND9ACN250A高速线束应用解析
  • 如何快速搭建ROS机器人仿真环境:完整实战指南
  • 感谢雷总!Mimo大模型价值¥659/月的 MAX 套餐,让我免费领到了!
  • 别再纠结swap分区了!聊聊现代Linux(Ubuntu 22.04/Debian 12)家用场景下swapfile的配置与性能取舍
  • GD32F407+LWIP实战:5分钟搞定UDP/TCP双协议回环测试
  • 终极指南:3大突破,如何高效释放硬件潜能实现游戏性能优化
  • ARM7嵌入式开发:从GCC工具链到外设驱动的Sceptre开发板实战指南
  • UnityWebRequest请求HTTPS接口总报错?别慌,这份SSL证书验证避坑指南请收好