Binder系列2-ServiceManager
Posted xhBruce
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Binder系列2-ServiceManager相关的知识,希望对你有一定的参考价值。
Binder系列2-ServiceManager
android12-release
ServiceManager是Binder IPC通信过程中的守护进程,本身也是一个Binder服务。
ServiceManager 其功能:查询和注册服务。 对于Binder IPC通信过程中,其实更多的情形是BpBinder和BBinder之间的通信,比如ActivityManagerProxy和ActivityManagerService之间的通信等。
1. ServiceManager启动
ServiceManager是由init进程通过解析init.rc文件而创建的,其所对应的可执行程序/system/bin/servicemanager,所对应的源文件是service_manager.c,进程名为/system/bin/servicemanager。
与原来的 servicemanager 服务相比较,使用了 libbinder
1.1 servicemanager.rc
- init进程解析
servicemanager.rc
,启动调用main.cpp
frameworks/native/cmds/servicemanager/Android.bp
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 main
onrestart class_restart hal
onrestart class_restart early_hal
writepid /dev/cpuset/system-background/tasks
shutdown critical
1.2 启动初始化
ProcessState::initWithDriver(driver) -> init() -> ProcessState() -> open_driver() ->
初始化/dev/binder
;
open(driver, O_RDWR | O_CLOEXEC)
打开Binder Driver设备
ioctl(fd, BINDER_VERSION, &vers)
ioctl获取binder版本信息BINDER_VERSION
ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads)
设置Binder线程最大个数,默认#define DEFAULT_MAX_BINDER_THREADS 15
ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable)
启用单向SPAM检测mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0)
mmap内存映射- Access.cpp中
selinux_status_open(true)
selinux权限启动,用于鉴权 manager->addService("manager", manager, ...)
初始化ServiceManager,addService
将自身注册到ServiceManager当中IPCThreadState::self()->setTheContextObject(manager)
将ServiceManager设置给IPCThreadState的全局变量ps->becomeContextManager()
BINDER_SET_CONTEXT_MGR 注册到 Binder Driver,成为上下文的管理者BinderCallback::setupTo(looper)
通知Binder Driver驱动BC_ENTER_LOOPER,LooperCallback监听驱动fd,有消息时回调到handleEvent处理ClientCallbackCallback::setupTo(looper, manager)
Client注册监听相关- 无限循环等消息,执行
looper->pollAll(-1)
;Android 11 之前是通过binder_loop方法,而现在是通过 looper。
frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv)
if (argc > 2)
LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
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);
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;
frameworks/native/libs/binder/ProcessState.cpp
static int open_driver(const char *driver)
int fd = open(driver, O_RDWR | O_CLOEXEC);
if (fd >= 0)
int vers = 0;
status_t result = ioctl(fd, BINDER_VERSION, &vers);
if (result == -1)
ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
close(fd);
fd = -1;
if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION)
ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
close(fd);
fd = -1;
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)
ALOGD("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
else
ALOGW("Opening '%s' failed: %s\\n", driver, strerror(errno));
return fd;
ProcessState::ProcessState(const char *driver)
: mDriverName(String8(driver))
, mDriverFD(open_driver(driver))
, mVMStart(MAP_FAILED)
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
, mExecutingThreadsCount(0)
, mWaitingForThreads(0)
, mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
, mStarvationStartTimeMs(0)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
, mCallRestriction(CallRestriction::NONE)
if (mDriverFD >= 0)
// 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, mDriverFD, 0);
if (mVMStart == MAP_FAILED)
// *sigh*
ALOGE("Using %s failed: unable to mmap transaction memory.\\n", mDriverName.c_str());
close(mDriverFD);
mDriverFD = -1;
mDriverName.clear();
#ifdef __ANDROID__
LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver '%s' could not be opened. Terminating.", driver);
#endif
frameworks/native/cmds/servicemanager/Access.cpp
Access::Access()
union selinux_callback cb;
cb.func_audit = auditCallback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
cb.func_log = kIsVendor ? selinux_vendor_log_callback : selinux_log_callback;
selinux_set_callback(SELINUX_CB_LOG, cb);
CHECK(selinux_status_open(true /*fallback*/) >= 0);
CHECK(getcon(&mThisProcessContext) == 0);
frameworks/native/cmds/servicemanager/ServiceManager.cpp
ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access))
1.3 时序图
2. 获取defaultServiceManager()
例如
media.player
、instatlld
、BootAnimation
进程都使用binder通行,见得比较多的是第三副图BinderService中publish()
2.1 defaultServiceManager()方法
std::call_once
处理只需要被调用一次或者初始化一次操作,C++11中提供;该方法就是单例模式。ProcessState::self()
用于获取ProcessState对象(也是单例模式)getContextObject(nullptr)
用于获取BpBinder(0)
对象interface_cast<AidlServiceManager>
使用IInterface.h
模板类获取BpServiceManager
对象,sp<AidlServiceManager>
等价于new BpServiceManager(new BpBinder(0))
- 最终获取
IServiceManager.cpp
中gDefaultServiceManager = sp<ServiceManagerShim>::make(sm)
frameworks/native/libs/binder/IServiceManager.cpp
using AidlServiceManager = android::os::IServiceManager;
sp<IServiceManager> defaultServiceManager()
std::call_once(gSmOnce, []()
sp<AidlServiceManager> sm = nullptr;
while (sm == nullptr)
sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
if (sm == nullptr)
ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str());
sleep(1);
gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
);
return gDefaultServiceManager;
2.2 BinderService.h模板interface_cast
AidlServiceManager = android::os::IServiceManager
带入模板::android::sp<Bp##INTERFACE>::make(obj)
实质new BpServiceManager()
frameworks/native/libs/binder/include/binder/BinderService.h
//... ...
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
return INTERFACE::asInterface(obj);
//... ...
static ::android::sp<I##INTERFACE> asInterface( \\
const ::android::sp<::android::IBinder>& obj); \\
//... ...
::android::sp<I##INTERFACE> I##INTERFACE::asInterface( \\
const ::android::sp<::android::IBinder>& obj) \\
\\
::android::sp<I##INTERFACE> intr; \\
if (obj != nullptr) \\
intr = ::android::sp<I##INTERFACE>::cast( \\
obj->queryLocalInterface(I##INTERFACE::descriptor)); \\
if (intr == nullptr) \\
intr = ::android::sp<Bp##INTERFACE>::make(obj); \\
\\
\\
return intr; \\
\\
2.3 时序图
3. 注册服务(addService)
3.1 addService客户端
3.1.1 installd通过BinderService注册
- 通过BinderService注册调用
sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated, dumpFlags)
,注册服务"installd"
defaultServiceManager()
获取BpServiceManager对象ps(ProcessState::self())
获得ProcessState实例对象ps->startThreadPool()
启动Binder线程池,IPCThreadState::self()->joinThreadPool()
当前线程加入到线程池
frameworks/native/cmds/installd/installd.cpp
static int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[])
// ... ...
if ((ret = InstalldNativeService::start()) != android::OK)
SLOGE("Unable to start InstalldNativeService: %d", ret);
exit(1);
IPCThreadState::self()->joinThreadPool();
// ... ...
frameworks/native/cmds/installd/InstalldNativeService.cpp
status_t InstalldNativeService::start()
IPCThreadState::self()->disableBackgroundScheduling(true);
status_t ret = BinderService<InstalldNativeService>::publish();
if (ret != android::OK)
return ret;
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
ps->giveThreadPoolName();
sAppDataIsolationEnabled = android::base::GetBoolProperty(
kAppDataIsolationEnabledProperty, true);
return android::OK;
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT)
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
dumpFlags);
3.1.2 SM注册请求
mTheRealServiceManager
是android::os::IServiceManager 类型的实例,在 ServiceManagerShim 实例化时赋值。BpServiceManager#addService
方法aidl自动编译生成文件out/.../frameworks/native/libs/binder/libbinder/.../aidl/android/os/IServiceManager.cpp
- 参照Android 11之前
BpServiceManager#addService
实现实质一样的,Parcel
数据结构传递 Parcel
作为接收的数据,其中writeUtf8AsUtf16(name)
与Android 11之前不同,有个格式转换BpServiceManager->BpBinder->IPCThreadState->ioctl
层层调用后,ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)
与Binder Driver
通信;Binder Driver
根据handle == 0
找到对端 servicemanager 进程,唤醒他开始处理请求
frameworks/native/libs/binder/IServiceManager.cpp
status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated, int dumpsysPriority)
Status status = mTheRealServiceManager->addService(
String8(name).c_str(), service, allowIsolated, dumpsysPriority);
return status.exceptionCode();
Android 11之前BpServiceManager–>BpBinder–>IPCThreadState–>ioctl
frameworks/native/libs/binder/Parcel.cpp
status_t Parcel::writeUtf8AsUtf16(const std::string& str)
const uint8_t* strData = (uint8_t*)str.data();
const size_t strLen= str.length();
const ssize_t utf16Len = utf8_to_utf16_length(strData, strLen);
if (utf16Len < 0 || utf16Len > std::numeric_limits<int32_t>::max())
return BAD_VALUE;
status_t err = writeInt32(utf16Len);
if (err)
return err;
// Allocate enough bytes to hold our converted string and its terminating NULL.
void* dst = writeInplace((utf16Len + 1) * sizeof(char16_t));
if (!dst)
return NO_MEMORY;
utf8_to_utf16(strData, strLen, (char16_t*)dst, (size_t) utf16Len + 1);
return NO_ERROR;
3.1.3 时序图
3.2 addService服务端
3.2.1 Binder Driver唤醒处理handleEvent()
ServiceManager启动
中BinderCallback监听,客户端请求Binder Driver
唤醒处理handleEvent()
handleEvent() -> ... -> executeCommand() -> BBinder#transact -> BnServiceManager#onTransact()
最终通过onTransact调用到和Bp端是对称的操作ServiceManager.cpp::addService
方法BnServiceManager#onTransact()
方法也是aidl自动编译生成文件out/.../frameworks/native/libs/binder/libbinder/.../aidl/android/os/IServiceManager.cpp
the_context_object
class BinderCallback : public LooperCallback
public:
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.
;
frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::executeCommand(int32_t cmd)
// ... ...
case BR_TRANSACT以上是关于Binder系列2-ServiceManager的主要内容,如果未能解决你的问题,请参考以下文章