Android ServiceManager和它的兄弟们
The following article is from 牛晓伟 Author 牛晓伟
本文摘要
java进程之间通信、java与native进程 (除hal进程)之间通信、native进程 (除hal进程)之间通信都用binder进行通信。 非hal进程与hal进程之间通信使用hwbinder进行通信。 hal进程之间通信使用vndbinder进行通信。
vold:“都宝贝宝贝叫了,还说不偏心。”
出生
//文件路径:/frameworks/native/cmds/servicemanager/servicemanager.rc
service servicemanager /system/bin/servicemanager
class core animation
user system
group system readproc
critical
onrestart restart apexd
onrestart restart audioserver
onrestart restart gatekeeperd
onrestart class_restart --only-enabled main
onrestart class_restart --only-enabled hal
onrestart class_restart --only-enabled early_hal
task_profiles ServiceCapacityLow
shutdown critical
//文件路径:/frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
省略代码......
}
长大成人
binder驱动会把servicemanager进程的信息pid、uid (uid也就是app安装时候生成的id)等关键信息记录下来,并且会返回一个fd (fd文件描述符,是一个int类型),在后面与binder驱动通信过程中都需要带上该fd (通过它可以找到记录下来的信息)。 进行mmap操作 (用户空间与内核空间进行内存映射,这也是binder通信只需一次拷贝的关键)。 构建并返回ProcessState对象,在一个进程中只存在一个实例。
//文件路径:/frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
if (argc > 2) {
LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
}
//argc==2则使用argv[1],否则使用/dev/binder驱动,当前servicemanager进程会使用/dev/binder
const char* driver = argc == 2 ? argv[1] : "/dev/binder";
//该方法会打开binder驱动
sp<ProcessState> ps = ProcessState::initWithDriver(driver);
省略代码......
}
告知binder驱动我servicemanager进程配置的最大线程数是0。 如果设置成功了,ProcessState也会更新最大线程数。
//文件路径:/frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
省略代码......
//设置最大线程数
ps->setThreadPoolMaxThreadCount(0);
省略代码......
}
//文件路径:/frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
省略代码......
sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
LOG(ERROR) << "Could not self register servicemanager";
}
IPCThreadState::self()->setTheContextObject(manager);//manager会处理各种transaction
省略代码......
}
//文件路径:/frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
省略代码......
ps->becomeContextManager();
省略代码......
}
//文件路径:/frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
省略代码......
//当前线程创建Looper
sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
BinderCallback::setupTo(looper);
ClientCallbackCallback::setupTo(looper, manager);
//进入无限循环
while(true) {
looper->pollAll(-1);
}
}
//文件路径:/frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
//获取驱动名称。如果argc==2,则使用argv[1],argv[1]为 /dev/vndbinder,否则使用 /dev/binder
const char* driver = argc == 2 ? argv[1] : "/dev/binder";
sp<ProcessState> ps = ProcessState::initWithDriver(driver);
ps->setThreadPoolMaxThreadCount(0);
ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
LOG(ERROR) << "Could not self register servicemanager";
}
IPCThreadState::self()->setTheContextObject(manager);//manager会处理各种transaction
ps->becomeContextManager();
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;
}
如何得到我
添加服务
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
省略代码......
}
//Service定义
struct Service {
sp<IBinder> binder; // not null
bool allowIsolated;
int32_t dumpPriority;
bool hasClients = false; // notifications sent on true -> false.
bool guaranteeClient = false; // forces the client check to true
pid_t debugPid = 0; // the process in which this service runs
// the number of clients of the service, including servicemanager itself
ssize_t getNodeStrongRefCount();
};
using ServiceMap = std::map<std::string, Service>;
ServiceMap mNameToService;
//文件路径:/frameworks/native/cmds/servicemanager/ServiceManager.cpp
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
省略掉权限检查相关的代码......
// Overwrite the old service if it exists
mNameToService[name] = Service {//构造Service对象,若存在会把原先的覆盖
.binder = binder,
.allowIsolated = allowIsolated,
.dumpPriority = dumpPriority,
.debugPid = ctx.debugPid,
};
auto it = mNameToRegistrationCallback.find(name);
if (it != mNameToRegistrationCallback.end()) {
for (const sp<IServiceCallback>& cb : it->second) {
mNameToService[name].guaranteeClient = true;
// permission checked in registerForNotifications
cb->onRegistration(name, binder);//告知监听者监听的name和binder已经注册了
}
}
return Status::ok();
}
移除服务
//文件路径:/frameworks/native/cmds/servicemanager/ServiceManager.cpp
void ServiceManager::binderDied(const wp<IBinder>& who) {
//从mNameToService中进行查找,找到了则从mNameToService中移除掉
for (auto it = mNameToService.begin(); it != mNameToService.end();) {
if (who == it->second.binder) {
it = mNameToService.erase(it);
} else {
++it;
}
}
省略代码......
}
获取服务
Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
*outBinder = tryGetService(name, true);
// returns ok regardless of result for legacy reasons
return Status::ok();
}
void ServiceManager::tryStartService(const std::string& name) {
ALOGI("Since '%s' could not be found, trying to start it as a lazy AIDL service",
name.c_str());
std::thread([=] {
//调用SetProperty方法后,init进程会收到"ctl.interface_start"属性的变化,进而开始启动对应的service
if (!base::SetProperty("ctl.interface_start", "aidl/" + name)) {
LOG(INFO) << "Tried to start aidl service " << name
<< " as a lazy service, but was unable to. Usually this happens when a "
"service is not installed, but if the service is intended to be used as a "
"lazy service, then it may be configured incorrectly.";
}
}).detach();
}
异步获取服务
有没有使用者
Status ServiceManager::registerClientCallback(const std::string& name, const sp<IBinder>& service,
const sp<IClientCallback>& cb) {
省略各种校验的代码......
//mNameToClientCallback也是一个map,key值为name,value为IClientCallback
mNameToClientCallback[name].push_back(cb);
return Status::ok();
}
//文件路径:/frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
省略代码.......
//main方法中会调用ClientCallbackCallback的setupTo方法初始化,ClientCallbackCallback类setupTo方法请查看[1.1]
ClientCallbackCallback::setupTo(looper, manager);
while(true) {
looper->pollAll(-1);
}
// should not be reached
return EXIT_FAILURE;
}
class ClientCallbackCallback : public LooperCallback {
public:
[1.1]
static sp<ClientCallbackCallback> setupTo(const sp<Looper>& looper, const sp<ServiceManager>& manager) {
sp<ClientCallbackCallback> cb = sp<ClientCallbackCallback>::make(manager);
//创建clock对应的fd
int fdTimer = timerfd_create(CLOCK_MONOTONIC, 0 /*flags*/);
//间隔5s
itimerspec timespec {
.it_interval = {
.tv_sec = 5,
.tv_nsec = 0,
},
.it_value = {
.tv_sec = 5,
.tv_nsec = 0,
},
};
省略代码......
//looper监听fdTimer,每5s会执行一次cb也就是下面的handleEvent方法
int addRes = looper->addFd(fdTimer,
Looper::POLL_CALLBACK,
Looper::EVENT_INPUT,
cb,
nullptr);
return cb;
}
//cb会执行该方法
int handleEvent(int fd, int /*events*/, void* /*data*/) override {
省略代码......
//每5s执行一次该方法,handleClientCallbacks请查看[1.2]
mManager->handleClientCallbacks();
return 1; // Continue receiving callbacks.
}
省略属性代码......
};
[1.2]
//文件路径:/frameworks/native/cmds/servicemanager/ServiceManager.cpp
void ServiceManager::handleClientCallbacks() {
//遍历所有添加的binder server
for (const auto& [name, service] : mNameToService) {
handleServiceClientCallback(name, true);
}
}
总结
这就是我,那接下来有请我家老二吧。
为何有我
hal:Hardware Abstraction Layer的缩写,意思为硬件抽象层,用于提供对硬件设备的抽象层
图解:
app调用某个service的能力比如打开聚光灯、打开振动。 对应的service会通过jni调用进入native层代码。 native层代码会加载硬件的so,并且调用hal的api。 hal的api最终会调用厂商的硬件实现 (驱动实现)来执行相应功能。
我哥servicemanager打开驱动时候使用的是/dev/binder,而我在打开驱动的时候用的是/dev/hwbinder,我同样也有“接口人”它的名字也是ServiceManager,关于我的“出生”、“长大成人”、“提供的能力”等就不在这赘述了,因为与我哥servicemanager的这些介绍都是一样的,它有的能力我有,他没有的我也没有,其实我的很多代码都是复制了它的代码,在此基础上做了改动。
vndservicemanager:“各位父老乡亲,大家好,我是vndservicemanager,vnd是vendor的缩写,我像我哥servicemanager一样,我也是一个系统native进程。我主要是为hal进程与hal进程进行vdnbinder通信服务的。vndbinder通信其实和binder通信也是一样的,换了个名字而已。我和servicemanager完全用了一套同样的代码,只不过在打开binder驱动的时候使用的是/dev/vndbinder,关于我就介绍到这。”
最后推荐一下我做的网站,玩Android: wanandroid.com ,包含详尽的知识体系、好用的工具,还有本公众号文章合集,欢迎体验和收藏!
推荐阅读:
扫一扫 关注我的公众号
如果你想要跟大家分享你的文章,欢迎投稿~
┏(^0^)┛明天见!