文章目录
- 关注 ServiceMager 原因
- ServerManager需要掌握的知识
- 资料参考
- ServiceManager 进程启动
- 启动脚本
- 涉及到的相关源码文件
- 源码跟踪
- ServiceManager脚本启动位置
- ServiceManager关联脚本
- Native层源码分析
- main.cpp
- 流程
- 打开驱动 initWithDriver
- init
- make
- ProcessState 构造方法
- open_driver(driver)
- 注册成Binder服务 addService
- 注册成Binder服务 becomeContextManager
- 轮询
- 解析命令,执行命令
- 总结
关注 ServiceMager 原因
-
理解实现的原理
-
Framework层核心内容Service,绝绝大部分离不开ServiceManager的,framework层的各种Service
都和ServiceManager打交道的。应用层调用系统Service也是和ServiceManager 关联的, -
方便后面理解各种Service源码
-
Binder 机制了解 怎么可能不去熟悉ServiceManager
ServerManager需要掌握的知识
资料参考
ServiceManager(Native)启动分析
系统服务大管家-ServiceManager
启动ServiceManager
ServiceManager__29">ServiceManager 进程启动
我们需要从两方面分析,Native层和framework层,本章我们作为 ServiceManager 源码的开篇,仅关注启动相关源码分析
为什么把ServiceManager 启动单独拿出来:方便分析,一步一个脚印理解。
启动脚本
涉及到的相关源码文件
为了方便理解,暂不用实际平台项目作为参考,直接用谷歌一套来check 源码的开篇,仅关注启动相关源码分析
部分路径和平台源码路径不一致很正常,在实际开发中以实际各个OEM厂商源码 位置为准。
在线源码XrefAndroid:
init.rc
servicemanager
/bootable/recovery/etc/init.rc
/frameworks/native/cmds/servicemanager/servicemanager.rc
源码跟踪
ServiceManager_48">ServiceManager脚本启动位置
ServiceManager是在rc脚本中启动的:
/bootable/recovery/etc/init.rc 中
# Start essential services
start servicemanager
ServiceManager_57">ServiceManager关联脚本
servicemanager服务定义在frameworks\native\cmds\servicemanager\servicemanager.rc。
可以看到,servicemanger是一个Linux程序,它在设备中的存储路径是/system/bin/servicemanager,源码路径则是/frameworks/native/cmds/servicemanager。
service servicemanager /system/bin/servicemanager
class core animation #表示这是一个核心服务,系统启动时优先运行
user system # 以 system 用户身份运
group system readproc
critical # 标记为关键服务,如果退出会触发系统重启
onrestart restart apexd # 如果servicemanager重启 则 apexd也会重启
onrestart restart audioserver # 如果servicemanager重启 则 audioserver
onrestart restart gatekeeperd # 如果servicemanager重启 则 audioserver
onrestart class_restart --only-enabled main
onrestart class_restart --only-enabled hal
onrestart class_restart --only-enabled early_hal
task_profiles ServiceCapacityLow
shutdown critical
简单介绍下这个文件脚本:
满足条件后执行程序 /system/bin/servicemanager,去Android 下面查看,果然有。
Native层源码分析
上面已经分析了servicemanager.rc 脚本了,我们看看该模块下的编译文件Android.bp
cc_binary {
name: "servicemanager",
defaults: ["servicemanager_defaults"],
init_rc: ["servicemanager.rc"],
srcs: ["main.cpp"],
}
这里就定位到了资源文件 main.cpp
main.cpp
int main(int argc, char** argv) {
#ifdef __ANDROID_RECOVERY__
android::base::InitLogging(argv, android::base::KernelLogger);
#endif
if (argc > 2) {
LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
}
const char* driver = argc == 2 ? argv[1] : "/dev/binder"; //检查输入参数,如果参数为空,则driver为"/dev/binder"
sp<ProcessState> ps = ProcessState::initWithDriver(driver); //创建ProcessState对象(进程唯一),并进行open、ioctl、mmap操作态
ps->setThreadPoolMaxThreadCount(0); // 设置Binder线程池的最大线程数为0(表示使用默认设置)
ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>()); //创建自己这个对象,构造自己时构造Access对象,这个是用于权限检测
//先注册自己作为服务
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
LOG(ERROR) << "Could not self register servicemanager";
}
//保存ServiceManager作为BBinder对象到IPCThreadState实例中
IPCThreadState::self()->setTheContextObject(manager);
//向驱动注册自己成为全局唯一的ContextManager,全局只有一个ServiceManager
ps->becomeContextManager();
sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/); //获取一个Looper
BinderCallback::setupTo(looper); //将binder fd添加到Looper中监听,当驱动有事件时,回调handleEvent()处理
ClientCallbackCallback::setupTo(looper, manager); //这个是用于告知客户端当前服务端有多少个客户端绑定的回调监听
//循环等待事件到来
while(true) {
//阻塞等待event的到来,然后进行ioctl和驱动交互获取数据
looper->pollAll(-1);
}
// should not be reached
return EXIT_FAILURE;
}
流程
上面的main方,可以分析Service启动流程的,我们先给出流程图,下一步一步一步分析说明
上面列举了main方法,给出了流程图,下面具体分析核心方法,具体在启动时候做了哪些动作
打开驱动 initWithDriver
initWithDriver
/frameworks/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::initWithDriver(const char* driver)
{
return init(driver, true /*requireDefault*/);
}
init
sp<ProcessState> ProcessState::init(const char *driver, bool requireDefault)
{
................
std::call_once(gProcessOnce, [&](){
if (access(driver, R_OK) == -1) {
ALOGE("Binder driver %s is unavailable. Using /dev/binder instead.", driver);
driver = "/dev/binder";
}
// we must install these before instantiating the gProcess object,
// otherwise this would race with creating it, and there could be the
// possibility of an invalid gProcess object forked by another thread
// before these are installed
int ret = pthread_atfork(ProcessState::onFork, ProcessState::parentPostFork,
ProcessState::childPostFork);
LOG_ALWAYS_FATAL_IF(ret != 0, "pthread_atfork error %s", strerror(ret));
std::lock_guard<std::mutex> l(gProcessMutex);
gProcess = sp<ProcessState>::make(driver);
});
......
verifyNotForked(gProcess->mForked);
return gProcess;
}
这里注意核心 内容 方法 make, 就是通过智能指针创建了ProcessState对象,走一遍构造方法。
Sp 关联的强指针-若指针参考
make
先看下make 方法位置和定义,在StrongPointer.h 里面
StrongPointer.h
// TODO: Ideally we should find a way to increment the reference count before running the
// constructor, so that generating an sp<> to this in the constructor is no longer dangerous.
template <typename T>
template <typename... Args>
sp<T> sp<T>::make(Args&&... args) {
T* t = new T(std::forward<Args>(args)...);
sp<T> result;
result.m_ptr = t;
t->incStrong(t); // bypass check_not_on_stack for heap allocation
return result;
}
所以 m sp::make(driver) 回去执行 ProcessState 构造方法
ProcessState 构造方法
ProcessState::ProcessState(const char* driver)
: mDriverName(String8(driver)),
mDriverFD(-1),
mVMStart(MAP_FAILED),
mThreadCountLock(PTHREAD_MUTEX_INITIALIZER),
mThreadCountDecrement(PTHREAD_COND_INITIALIZER),
mExecutingThreadsCount(0),
mWaitingForThreads(0),
mMaxThreads(DEFAULT_MAX_BINDER_THREADS),
mStarvationStartTimeMs(0),
mForked(false),
mThreadPoolStarted(false),
mThreadPoolSeq(1),
mCallRestriction(CallRestriction::NONE) {
base::Result<int> opened = open_driver(driver);
if (opened.ok()) {
// mmap the binder, providing a chunk of virtual address space to receive transactions.
mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE,
opened.value(), 0);
if (mVMStart == MAP_FAILED) {
close(opened.value());
// *sigh*
opened = base::Error()
<< "Using " << driver << " failed: unable to mmap transaction memory.";
mDriverName.clear();
}
}
#ifdef __ANDROID__
LOG_ALWAYS_FATAL_IF(!opened.ok(), "Binder driver '%s' could not be opened. Terminating: %s",
driver, opened.error().message().c_str());
#endif
if (opened.ok()) {
mDriverFD = opened.value();
}
}
open_driver(driver)
这里不就是打开驱动的逻辑嘛
static base::Result<int> open_driver(const char* driver) {
int fd = open(driver, O_RDWR | O_CLOEXEC);
if (fd < 0) {
return base::ErrnoError() << "Opening '" << driver << "' failed";
}
int vers = 0;
status_t result = ioctl(fd, BINDER_VERSION, &vers);
if (result == -1) {
close(fd);
return base::ErrnoError() << "Binder ioctl to obtain version failed";
}
if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
close(fd);
return base::Error() << "Binder driver protocol(" << vers
<< ") does not match user space protocol("
<< BINDER_CURRENT_PROTOCOL_VERSION
<< ")! ioctl() return value: " << result;
}
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
if (result == -1) {
ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
}
uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
if (result == -1) {
ALOGE_IF(ProcessState::isDriverFeatureEnabled(
ProcessState::DriverFeature::ONEWAY_SPAM_DETECTION),
"Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
}
return fd;
}
在打开驱动时候进行了 ioctl 控制操作
注册成Binder服务 addService
ServiceManager.cpp
将ServiceManager这个服务保存中mNameToService中,回调服务onRegistration()方法。其实ServiceManager也是一个服务,用来管理其他服务,在其他服务启动注册前就已经就绪了。
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
auto ctx = mAccess->getCallingContext();
if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
return Status::fromExceptionCode(Status::EX_SECURITY, "App UIDs cannot add services");
}
if (!mAccess->canAdd(ctx, name)) {
return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denial");
}
if (binder == nullptr) {
return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Null binder");
}
if (!isValidServiceName(name)) {
LOG(ERROR) << "Invalid service name: " << name;
return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Invalid service name");
}
#ifndef VENDORSERVICEMANAGER
if (!meetsDeclarationRequirements(binder, name)) {
// already logged
return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "VINTF declaration error");
}
#endif // !VENDORSERVICEMANAGER
// implicitly unlinked when the binder is removed
if (binder->remoteBinder() != nullptr &&
binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
LOG(ERROR) << "Could not linkToDeath when adding " << name;
return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, "linkToDeath failure");
}
// Overwrite the old service if it exists
mNameToService[name] = 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);
}
}
return Status::ok();
}
注册成Binder服务 becomeContextManager
其实就是通过ioctl 给系统发送了一条指令 BINDER_SET_CONTEXT_MGR_EXT,驱动被认定这个进程是ServiceManager.
android binder驱动层-BINDER_SET_CONTEXT_MGR_EXT
bool ProcessState::becomeContextManager()
{
AutoMutex _l(mLock);
flat_binder_object obj {
.flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX,
};
int result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR_EXT, &obj);
// fallback to original method
if (result != 0) {
android_errorWriteLog(0x534e4554, "121035042");
int unused = 0;
result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &unused);
}
if (result == -1) {
ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
}
return result == 0;
}
轮询
开启了死循环,通过Looper不停的pull,回调给相应的LooperCallback
sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
BinderCallback::setupTo(looper);
ClientCallbackCallback::setupTo(looper, manager);
while(true) {
looper->pollAll(-1);
}
setupTo 方法:轮询读取命令
static sp<BinderCallback> setupTo(const sp<Looper>& looper) {
sp<BinderCallback> cb = sp<BinderCallback>::make();
int binder_fd = -1;
IPCThreadState::self()->setupPolling(&binder_fd);
LOG_ALWAYS_FATAL_IF(binder_fd < 0, "Failed to setupPolling: %d", binder_fd);
int ret = looper->addFd(binder_fd,
Looper::POLL_CALLBACK,
Looper::EVENT_INPUT,
cb,
nullptr /*data*/);
LOG_ALWAYS_FATAL_IF(ret != 1, "Failed to add binder FD to Looper");
return cb;
}
int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
IPCThreadState::self()->handlePolledCommands();
return 1; // Continue receiving callbacks.
}
};
解析命令,执行命令
上面轮训中看到 处理指令 handleEvent,最终回调方法是handlePolledCommands
status_t IPCThreadState::handlePolledCommands()
{
status_t result;
do {
result = getAndExecuteCommand();
} while (mIn.dataPosition() < mIn.dataSize());
processPendingDerefs();
flushCommands();
return result;
}
总结
- 了解ServiceManager 进程的启动,脚本和Native基本知识
- 通过ServiceManager 的启动,为后续ServieManager的注册、获取、Binder和Service的交互打一个小基础