ServiceManager在init进程启动之后启动,用来管理系统中的service注册、查找、通讯等。
1、注册:首先会检查是否有权限注册service,如果没有权限就直接返回不能注册;然后去检查该service是否已经注册过了,如果已经注册过,那就不能再注册;再判断内存是否够用。如果都没有问题,就会注册该service,加入到svcList中来,(在servicemanager中维护service信息的地方就是svcList,里面存了service的name和handler)。
2、查找:通过name从svcList找到对应等service,返回对应的handler
3、通讯:ServiceManager以类似Loop的工作方式不断从Binder设备中读取消息,发送给对应的service;若没有消息,则会进入等待状态,等待新消息到来再被激活;由于每个App只能打开一次Binder设备,做一次内存映射,所有需要使用binder驱动的线程共享这一资源,即共享同一个ServiceManager。
ServiceManager的启动
所有的系统服务都是需要在ServiceManager中进行注册的,而ServiceManager作为一个起始的服务,是通过init.rc来启动的。
arduino
//system\core\rootdir\init.rc
//启动的服务,这里是用的服务名称。服务名称是在对应的rc文件中注册并启动的
start servicemanager
具体的服务信息是在servicemanger.rc命名并定义的
kotlin
//\frameworks\native\cmds\servicemanager\servicemanager.rc
service servicemanager /system/bin/servicemanager
class core animation
user system //说明以用户system身份运行
group system readproc
//说明servicemanager是系统中的关键服务,
//关键服务是不会退出的,如果退出了,系统就会重启,当系统重启时就会启动用onrestart关键字修饰的进程,
//比如zygote、media、surfaceflinger等等。
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart audioserver
onrestart restart media
onrestart restart surfaceflinger
onrestart restart inputflinger
onrestart restart drm
onrestart restart cameraserver
onrestart restart keystore
onrestart restart gatekeeperd
onrestart restart thermalservice
..
servicemanager的入口函数在frameworks\native\cmds\servicemanager\main.cpp中
代码如下:
rust
int main(int argc, char** argv) {
//根据上面的rc文件,argc == 1, argv[0] == "/system/bin/servicemanager"
if (argc > 2) {
LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
}
//此时,要使用的binder驱动为/dev/binder
const char* driver = argc == 2 ? argv[1] : "/dev/binder";
//初始化binder驱动
sp<ProcessState> ps = ProcessState::initWithDriver(driver);
ps->setThreadPoolMaxThreadCount(0);
ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
//实例化ServiceManager
sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
//将自身作为服务添加
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
LOG(ERROR) << "Could not self register servicemanager";
}
//设置服务端Bbinder对象
IPCThreadState::self()->setTheContextObject(manager);
//设置成为binder驱动的context manager,成为上下文的管理者
ps->becomeContextManager(nullptr, nullptr);
//通过Looper epoll机制处理binder事务
sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
BinderCallback::setupTo(looper);
ClientCallbackCallback::setupTo(looper, manager);
while(true) {
looper->pollAll(-1);
}
// should not be reached
return EXIT_FAILURE;
}
具体的逻辑整理成长下面的流程图:
如上图,启动流程的变动主要在进入循环的方式,Android 11 之前是通过binder_loop方法,而现在是通过 looper。
和原来的 servicemanager 服务相比较,使用了 libbinder 后,代码更规范化,和其他 native 的服务风格一致了。
1)之前是直接 open、mmap 现在是借助 libbinder
2)之前是 binder_loop死 循环接收驱动的消息,现在是通过 looper 监听 fd 来handleEvent
3)之前的鉴权现在被独立到单独文件 Access.cpp
今日分享到此结束,对你有帮助的话,点个赞再走呗,如遇侵权联系删除
关注公众号:Android老皮解锁 《Android十大板块文档》 ,让学习更贴近未来实战。已形成PDF版
内容如下:
1.Android车载应用开发系统学习指南(附项目实战)
2.Android Framework学习指南,助力成为系统级开发高手
3.2023最新Android中高级面试题汇总+解析,告别零offer
4.企业级Android音视频开发学习路线+项目实战(附源码)
5.Android Jetpack从入门到精通,构建高质量UI界面
6.Flutter技术解析与实战,跨平台首要之选
7.Kotlin从入门到实战,全方面提升架构基础
8.高级Android插件化与组件化(含实战教程和源码)
9.Android 性能优化实战+360°全方面性能调优
10.Android零基础入门到精通,高手进阶之路