Binder是Android中非常非常重要的一个部分,它实现了进程间高效安全的通信。整个Binder系统整体上分为两个部分,一部分是Binder驱动,运行在内核中,也是跨进程的基石;一部分是Binder实体,封装了通信的逻辑,主要用来进行通信的,运行在用户空间中,提供各种服务。实体Binder中有一个特殊的存在ServiceManager,它只给服务来提供服务,用于管理服务的注册和查询。
学习Binder能够让我们对Android系统的理解更加深刻,更加清晰各个层级之间的关联。虽然在实际应用中我们几乎很难遇到裸用Binder的,但是想要在Framework上走的更深,Binder是必不可少的一环。并且实际面试中更是经常被问到,因此就算是为了应付面试,我们也应该仔细阅读Binder的实现。
本文基于Android 13源码
Binder的继承结构
Binder的设计独特的,它分出了两种Binder,一种是BBinder代表着服务实体,一种是BpBinder代表着服务的代理。在服务的实现中,它们继承自相同的接口并且分别实现了对应的方法。其中BBinder实现了具体的业务,而BpBinder封装了具体的跨进程调用,于是当一个进程拿到另一个进程对应的BpBinder后,就可以直接调用对应的方法,也就是通过同步调用的方式来实现跨进程的异步过程。
接下来先看下它们的继承结构:
IBinder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
class [[clang::lto_visibility_public]] IBinder : public virtual RefBase { public: IBinder(); virtual status_t transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) = 0;
virtual BBinder* localBinder(); virtual BpBinder* remoteBinder();
protected: virtual ~IBinder(); }
|
IBinder中定义了一些Binder的基础能力,所有的Binder都必须实现IBinder的接口,而IBinder又是继承自RefBase,因此可以使用智能指针去引用Binder。BBinder和BpBinder都是IBinder的实现类,从方法名字也能看到,他们分别代表本地Binder和远程Binder。注意这几个方法都是有着默认的空实现的。
BBinder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
class BBinder : public IBinder { public: BBinder(); virtual status_t transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) final;
virtual BBinder* localBinder(); protected: virtual ~BBinder(); virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
private: BBinder(const BBinder& o); BBinder& operator=(const BBinder& o); };
|
BBinder是本地实体Binder,它继承自IBinder,本身又定义了一个onTranscat方法。transact方法是跨进程发送的方法,因此它是在IBinder中定义的,但是onTransact表示的是接受跨进程调用,因此它只在BBinder中有,因为它才是服务的本体,才需要处理消息事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
BBinder* BBinder::localBinder() { return this; }
status_t BBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { ... status_t err = NO_ERROR; switch (code) { ... default: err = onTransact(code, data, reply, flags); break; } ... return err; }
status_t BBinder::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t ) { switch (code) { case INTERFACE_TRANSACTION: reply->writeString16(getInterfaceDescriptor()); return NO_ERROR; case DUMP_TRANSACTION: { ... return dump(fd, args); } case SHELL_COMMAND_TRANSACTION: { ... return NO_ERROR; } case SYSPROPS_TRANSACTION: { report_sysprop_change(); return NO_ERROR; } default: return UNKNOWN_TRANSACTION; } }
|
对于本地Binder,localBinder返回的就是它本身,而remoteBinder则是默认的返回nullptr。同样的,在transact方法中,会直接走到onTransact中。这是因为它是本地实体,当通过实体Binder的transact方法发送消息的时候,实际是不需要经过跨进程的而是直接就能获取到消息,因此不需要处理发送的细节,而是直接将请求发回给onTransact中进行处理即可。
BpBinder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
class BpBinder : public IBinder { public: virtual status_t transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) final;
virtual BpBinder* remoteBinder();
private: static sp<BpBinder> create(int32_t handle); virtual ~BpBinder(); };
|
BpBinder是远程Binder的代理类,当客户端和服务端处于不同的进程时,客户端会获取到服务端BBinder实体的引用,然后将其包装成BpBinder,通过对BpBinder方法的调用来访问具体的业务,而这些方法最终会走到transact方法中去进行具体的跨进程逻辑。这里提供了一个create的方法来构建BpBinder,参数是handle。这个handle就是远程的服务本体BBinder在当前进程中的唯一索引,是通过SerciceManager查询到的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
BpBinder* BpBinder::remoteBinder() { return this; }
status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { if (mAlive) { ... status_t status; if (CC_UNLIKELY(isRpcBinder())) { status = rpcSession()->transact(sp<IBinder>::fromExisting(this), code, data, reply,flags); } else { status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags); } ... return status; } return DEAD_OBJECT; }
|
BpBinder在跨进程调用的时候,将参数和命令统一转发给了IPCThreadState去处理的,因此,我们在具体的服务代理实现中,只需要在对应的方法中封装code和data即可,最后通过transact发送消息即可。

ServiceManager
上面看了Binder的相关定义,大体上能看出它的设计理念:调用方拿到实体服务的handle去创建服务代理BpBinder,然后实现服务的方法,逻辑是封装code命令和data参数,最终通过transact发送。实体服务继承自BBinder,实现服务的方法并且在onTransact中解析code和data参数,然后调用自己对应的方法。
有了前面的基础我们再去看ServiceManager,前面看到调用方需要拿到实体服务的handle才能创建对应的代理服务BpBinder,这个handle就是通过ServiceManager拿到的。但是ServiceManager和调用方也不是在同一个进程,因此想要和ServiceManager交互就必须拿到ServiceManager的handle,而handle又得通过和ServiceManager交互才能拿到。。。想解决这个问题,只需要将ServiceManager的handle固定即可,就不需要查询了,因此它的值被固定成为0。这样所有的进程,都可以通过0的来创建ServiceManager的代理服务进而进行交互了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
int main(int argc, char** argv) { 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 , 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 ); BinderCallback::setupTo(looper); ClientCallbackCallback::setupTo(looper, manager); while(true) { looper->pollAll(-1); } return EXIT_FAILURE; }
|
开机时ServiceManager就会启动,它的启动逻辑就是上述逻辑。概述下来就是创建ServiceManager对象,然后注册到自身中,然后将自己设置为binder的管理者,然后开始进入阻塞等待Binder驱动的epoll唤醒,唤醒后再去处理相关的业务。
下面具体看下实现的细节,首先是ProcessState,它的定义在frameworks/native/libs/binder/include/binder/ProcessState.h,这里只是定义了它的一些方法,没什么可看的,直接看它的逻辑部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
sp<ProcessState> ProcessState::initWithDriver(const char* driver) { return init(driver, true ); }
[[clang::no_destroy]] static sp<ProcessState> gProcess; [[clang::no_destroy]] static std::mutex gProcessMutex; sp<ProcessState> ProcessState::init(const char *driver, bool requireDefault) { [[clang::no_destroy]] static std::once_flag gProcessOnce; std::call_once(gProcessOnce, [&](){ ... std::lock_guard<std::mutex> l(gProcessMutex); gProcess = sp<ProcessState>::make(driver); }); ... verifyNotForked(gProcess->mForked); return gProcess; }
|
也就是在initWithDriver的时候,会通过智能指针的sp::make创建ProcessState对象,并且这个对象是进程中的唯一单例对象。这里的make实际上就是调用了它的new方法创建的,所以直接看构造方法即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| 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()) { mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, opened.value(), 0); } if (opened.ok()) { mDriverFD = opened.value(); } }
static base::Result<int> open_driver(const char* driver) { int fd = open(driver, O_RDWR | O_CLOEXEC); int vers = 0; status_t result = ioctl(fd, BINDER_VERSION, &vers); size_t maxThreads = DEFAULT_MAX_BINDER_THREADS; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION; result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable); return fd; }
|
在ProcessState的构造方法中,对驱动做了一些基础的设置,如线程数、内存映射等操作。总的来说就是ProcessState是进程内单例的,用于和binder驱动建立连接的一个对象。它是通用的,因此在构造方法中就直接打开驱动并做了一些通用的设置,如设置最大线程数。继续回到启动ServiceManager的main方法中,在initWithDriver后,又重新设置了最大线程数为0:ps->setThreadPoolMaxThreadCount(0),也就是说ServiceManager中线程池的个数为0,即当前进程只会存在一个默认的主线程。
这里我们先不去看驱动的具体实现过程,而是把驱动作为一个黑盒来理解。我们只需要知道可以通过open打开驱动,通过ioctl进行设置和交互,至于具体实现后续再仔细研读。接下来继续回到main方法中,然后看ServiceManager的构造:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
class ServiceManager : public os::BnServiceManager, public IBinder::DeathRecipient { public: ServiceManager(std::unique_ptr<Access>&& access); ~ServiceManager();
binder::Status getService(const std::string& name, sp<IBinder>* outBinder) override; binder::Status checkService(const std::string& name, sp<IBinder>* outBinder) override; binder::Status addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) override; binder::Status listServices(int32_t dumpPriority, std::vector<std::string>* outList) override; ... private: struct Service { sp<IBinder> binder; ... }; using ServiceMap = std::map<std::string, Service>; ServiceMap mNameToService; ... };
|
ServiceManager是为了成为binder服务的管理者,它所相关的方法都是由用户查询和添加服务的,它有一个私有属性ServiceMap,用于存储注册的服务。可以看到它是继承自BnServiceManager的,这是AIDL生成的类,通常情况下我们使用AIDL都是在Java层中使用的,可以省下很多跨进程逻辑的编码。而在C++层也是可以使用AIDL的,它会生成对应的BnServiceManager和BpServiceManager,我们的本地实体服务继承自BnServiceManager,然后实现对应的逻辑。然后BpServiceManager中的逻辑是跨进程交互的逻辑,由AIDL直接生成,后面我们再看它生成的类。文件目录在:frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl
然后继续看构造方法和添加服务的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) { }
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) { ... mNameToService[name] = Service { .binder = binder, .allowIsolated = allowIsolated, .dumpPriority = dumpPriority, .debugPid = ctx.debugPid, }; ... return Status::ok(); }
|
这里仅是将自身添加到ServiceMap中存储下来,逻辑比较简单,因为这里也没有发生跨进程的调用,都是发生在ServiceManager的进程中的。添加服务后,它还会注册自己成为服务管理者,IPCThreadState::self()->setTheContextObject(manager)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
IPCThreadState* IPCThreadState::self() { if (gHaveTLS.load(std::memory_order_acquire)) { restart: const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); if (st) return st; return new IPCThreadState; } ... goto restart; }
IPCThreadState::IPCThreadState() : mProcess(ProcessState::self()), mServingStackPointer(nullptr), mServingStackPointerGuard(nullptr), mWorkSource(kUnsetWorkSource), mPropagateWorkSource(false), mIsLooper(false), mIsFlushing(false), mStrictModePolicy(0), mLastTransactionBinderFlags(0), mCallRestriction(mProcess->mCallRestriction) { pthread_setspecific(gTLS, this); clearCaller(); mIn.setDataCapacity(256); mOut.setDataCapacity(256); }
void IPCThreadState::setTheContextObject(const sp<BBinder>& obj) { the_context_object = obj; }
|
对于ProcessState,它是进程单例;对于IPCThreadState,它是线程单例。但是由于ServiceManager的线程池设置的为0,因此它们两个实际上都可以算是进程内单例的。然后IPCThreadState#setTheContextObject将自己设置为了服务管理者,对于其他进程的IPCThreadState,他们的the_context_obj实际上是空,所以当它们想获取ServiceManager的时候,就会通过handle为0的句柄去创建BpServiceManager。
最后一步是将自己注册到binder驱动中,因为它的handle是固定的,因此不需要将binder实体传入到驱动中,直接通过命令注册即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
bool ProcessState::becomeContextManager() { flat_binder_object obj { .flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX, }; int result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR_EXT, &obj); if (result != 0) { int unused = 0; result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &unused); } return result == 0; }
|
到这里ServiceManager的启动流程基本上已经完成了,首先就是通过ProcessState的初始化来打开binder驱动并建立内存映射,然后初始化IPCThreadState用于准备与驱动进行数据交互。最后就是启用looper循环了,然后将驱动的fd添加到epoll中监听binder的变化。可以查看native looper的实现细节,也可以查看epoll机制的机制的实现。
在启动looper循环之前,注册了一个BinderCallback:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
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); int ret = looper->addFd(binder_fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb, nullptr ); return cb; }
int handleEvent(int , int , void* ) override { IPCThreadState::self()->handlePolledCommands(); return 1; } };
int main(int argc, char** argv) { ... BinderCallback::setupTo(looper); ... }
|
在进入looper循环时,将驱动的fd添加到了looper中,这样每次驱动发生变化后,就会通知到ServiceManager,然后由ServiceManager的IPCThreadState去处理消息。同时还会通知到驱动自己已经进入到looper循环了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
status_t IPCThreadState::setupPolling(int* fd) { mOut.writeInt32(BC_ENTER_LOOPER); flushCommands(); *fd = mProcess->mDriverFD; return 0; }
void IPCThreadState::flushCommands() { talkWithDriver(false); if (mOut.dataSize() > 0) { talkWithDriver(false); } }
|
在通知到驱动自己进入循环的过程,实际上就是与驱动进行的一个交互。先向mOut写入数据,然后再往驱动中进行写入,在前面看IPCThreadState的时候我们知道它有两个私有属性mIn和mOut。其中mIn用于读取驱动发送来的数据,而mOut用来写入即将向驱动写入的数据。最终在talkWithDriver中完成实际的写入和读取:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
status_t IPCThreadState::talkWithDriver(bool doReceive) { binder_write_read bwr;
const bool needRead = mIn.dataPosition() >= mIn.dataSize(); const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0; bwr.write_size = outAvail; bwr.write_buffer = (uintptr_t)mOut.data();
if (doReceive && needRead) { bwr.read_size = mIn.dataCapacity(); bwr.read_buffer = (uintptr_t)mIn.data(); } else { bwr.read_size = 0; bwr.read_buffer = 0; }
if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
bwr.write_consumed = 0; bwr.read_consumed = 0; status_t err; do { if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0) err = NO_ERROR; else err = -errno; } while (err == -EINTR);
if (err >= NO_ERROR) { if (bwr.write_consumed > 0) { if (bwr.write_consumed < mOut.dataSize()) else { mOut.setDataSize(0); processPostWriteDerefs(); } } if (bwr.read_consumed > 0) { mIn.setDataSize(bwr.read_consumed); mIn.setDataPosition(0); } return NO_ERROR; } return err; }
|
talkWithDriver如其名字一样,与驱动进行交互。这个方法可以看到它不仅向驱动写入内容,也从驱动读取内容。当有内容需要写入到驱动的时候,先往mOut中写入,然后调用talkWithDriver写入到驱动中。如果想从驱动读取数据,需要先将mIn清空,然后调用talkWithDriver,然后就可以从mIn中读取到驱动写入的内容了。
然后看looper的回调,正常当向驱动发送数据后,驱动处理完之后会通知到epoll唤醒进程,进而回到looper中注册的回调,然后再走到IPCThreadState中处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
status_t IPCThreadState::handlePolledCommands() { status_t result; do { result = getAndExecuteCommand(); } while (mIn.dataPosition() < mIn.dataSize()); flushCommands(); return result; }
status_t IPCThreadState::getAndExecuteCommand() { status_t result; int32_t cmd; result = talkWithDriver(); if (result >= NO_ERROR) { cmd = mIn.readInt32(); result = executeCommand(cmd); ... } return result; }
|
重新整理下交互逻辑:ServiceManager实例化之后,将自己设置成为服务管理者,并通知到驱动。ProcessState负责打开驱动建立映射,IPCThreadState负责向驱动发送和读取数据。首先向mOut写入数据,然后talkWithDriver将数据发送给驱动,然后驱动读取数据并处理后通过epoll机制回调到looper进而再次走到IPCThreadState,然后再次talkWithDriver让驱动把数据写入到mIn中,然后在executeCommand方法中处理mIn中的数据。
到这里ServiceManager的启动逻辑基本上已经清楚了,与驱动交互的逻辑也基本上已经清楚了,这里我们没是将驱动作为黑盒看待的,具体的逻辑以及命令交互的过程都是没仔细看的,这个在后面讲驱动的时候再看了。
IServiceManager
前面我们看到的ServiceManager都是定义在frameworks/native/cmds/servicemanager下的,然后继承的BnServiceManager是aidl生成的。实际上,在Android10及以前,ServiceManager是用C语言实现的,没有类的概念也就没有ServiceManager,所有的逻辑都是由C的结构体实现的。
其他模块基本上都是用的C++,因此为了提供方法给其他模块调用,在frameworks/native/libs/binder/include/binder下定义了IServiceManager.h,并且在frameworks/native/libs/binder/目录下定义了IServiceManager.cpp实现了BpServiceManager类。
到了Android11以后,ServiceManager弃用了原来的C语言实现,和普通的服务一样使用更加通用的AIDL方式实现,声明文件在:frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl
编译后生成的文件在:out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_x86_64_shared/gen/aidl/android/os目录下。一共是四个文件:
IServiceManager.h:根据IServiceManager.aidl生成的接口IServiceManager.cpp:实现了BpServiceManager类的方法,通过Parcel中添加参数标记自己要调用的方法以及参数;实现了BnServiceManager中的onTransact方法,解析Parcel中的方法和参数,然后调用到自己本地的方法,然后将返回值再塞进Parcel中返回。BnServiceManager.h:代表着实体服务BpServiceManager.h:代表着远程代理服务
通过AIDL实现的ServiceManager更加易于阅读,同时也更容易管理,整个逻辑和Java层的AIDL也是一致的。但是,原本的IServiceManager怎么办?不能废弃了吧,因为很多的地方都在使用IServiceManager,如果直接废弃了而使用AIDL生成的新的IServiceManager改动起来就太多了。因此为了兼容,对老的IServiceManager进行改造,让它的内部持有一个新的AIDL生成的的ServiceManager,原来的方法都由新的SM来进行处理,这样就不需要改动到别的地方了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
namespace android {
class IServiceManager : public IInterface { public: virtual const String16& getInterfaceDescriptor() const; IServiceManager(); virtual ~IServiceManager(); virtual sp<IBinder> getService( const String16& name) const = 0; virtual sp<IBinder> checkService( const String16& name) const = 0; virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated = false, int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) = 0; virtual Vector<String16> listServices(int dumpsysFlags = DUMP_FLAG_PRIORITY_ALL) = 0; };
sp<IServiceManager> defaultServiceManager(); }
|
原本的IServiceManager和AIDL生成的类的方法基本上是一样的,但是方法的返回值可能会有一些差异,不过差异不大。另外,在IServiceManager.h中,在android的命名空间中增加了一个defaultServiceManager,用于获取到ServiceManager。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| using AidlServiceManager = android::os::IServiceManager;
const String16& IServiceManager::getInterfaceDescriptor() const { return AidlServiceManager::descriptor; } IServiceManager::IServiceManager() {} IServiceManager::~IServiceManager() {}
class ServiceManagerShim : public IServiceManager { public: explicit ServiceManagerShim (const sp<AidlServiceManager>& impl);
sp<IBinder> getService(const String16& name) const override; sp<IBinder> checkService(const String16& name) const override; status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated, int dumpsysPriority) override; Vector<String16> listServices(int dumpsysPriority) override;
protected: sp<AidlServiceManager> mTheRealServiceManager; };
[[clang::no_destroy]] static std::once_flag gSmOnce; [[clang::no_destroy]] static sp<IServiceManager> gDefaultServiceManager;
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) { sleep(1); } } gDefaultServiceManager = sp<ServiceManagerShim>::make(sm); }); return gDefaultServiceManager; }
ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl) : mTheRealServiceManager(impl) {}
sp<IBinder> ServiceManagerShim::getService(const String16& name) const { sp<IBinder> svc = checkService(name); if (svc != nullptr) return svc; int n = 0; while (uptimeMillis() - startTime < timeout) { n++; usleep(1000*sleepTime);
sp<IBinder> svc = checkService(name); if (svc != nullptr) { return svc; } } return nullptr; }
sp<IBinder> ServiceManagerShim::checkService(const String16& name) const { sp<IBinder> ret; if (!mTheRealServiceManager->checkService(String8(name).c_str(), &ret).isOk()) { return nullptr; } return ret; }
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(); }
Vector<String16> ServiceManagerShim::listServices(int dumpsysPriority) { std::vector<std::string> ret; if (!mTheRealServiceManager->listServices(dumpsysPriority, &ret).isOk()) { return {}; }
Vector<String16> res; res.setCapacity(ret.size()); for (const std::string& name : ret) { res.push(String16(name.c_str())); } return res; }
|
IServiceManager的实现类实际是ServiceManagerShim,它只是个包装类,实际的方法实现仍然是由AIDL的ServiceManager实现的,它只是起到包装的作用,并且修改了方法返回值等,以适配原本的IServiceManager。同时,它还额外添加了一个方法defaultServiceManager来获取默认的AIDL的ServiceManager,该方法返回的值仍然是进程单例的,在当前进程中只会存在一个ServiceManager。该方法实际是获取到ServiceManager的IBinder对象,然后转成IServiceManager的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& ) { sp<IBinder> context = getStrongProxyForHandle(0); return context; }
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; if (handle == 0 && the_context_object != nullptr) return the_context_object;
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) { IBinder* b = e->binder; if (b == nullptr || !e->refs->attemptIncWeak(this)) { if (handle == 0) { IPCThreadState* ipc = IPCThreadState::self(); Parcel data; status_t status = ipc->transact( 0, IBinder::PING_TRANSACTION, data, nullptr, 0); if (status == DEAD_OBJECT) return nullptr; } sp<BpBinder> b = BpBinder::PrivateAccessor::create(handle); e->binder = b.get(); if (b) e->refs = b->getWeakRefs(); result = b; } else { result.force_set(b); e->refs->decWeak(this); } } return result; }
|
getContextObject获取ServiceManager,如果是同一个进程则直接能拿到实体Binder,如果不是同一个进程则创建handle为0的BpBinder,反正最终结果是能拿到一个IBinder,然后再将其转换成IServiceManager就可以了,至于这个IServiceManager是实体服务还是远程代理服务都无所谓啦。

IServiceManager.aidl
一般来说,我们注册服务肯定是获取到IServiceManager,然后通过addService方法进行注册。经过前面的分析我们知道IServiceManager实际上是包装了AIDL的IServiceManager,因此我们可以看看AIDL生成的代码逻辑是怎么样的。注意,AOSP中只有IServiceManager.aidl文件的,想看实现的话必须将源码下载下来进行编译,编译之后才会有我们想要的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
::android::binder::Status BpServiceManager::addService(const ::std::string& name, const ::android::sp<::android::IBinder>& service, bool allowIsolated, int32_t dumpPriority) { ::android::Parcel _aidl_data; _aidl_data.markForBinder(remoteStrong()); ::android::Parcel _aidl_reply; ::android::status_t _aidl_ret_status = ::android::OK; ::android::binder::Status _aidl_status; _aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); _aidl_ret_status = _aidl_data.writeUtf8AsUtf16(name); _aidl_ret_status = _aidl_data.writeStrongBinder(service); _aidl_ret_status = _aidl_data.writeBool(allowIsolated); _aidl_ret_status = _aidl_data.writeInt32(dumpPriority); _aidl_ret_status = remote()->transact(BnServiceManager::TRANSACTION_addService, _aidl_data, &_aidl_reply, 0); _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); return _aidl_status; }
|
首先是往Parcel中写入数据,如服务的名字,服务的本体等。然后通过remote().transact方法进行跨进程的调用,其中remote()方法是定义在BpRefBase中的,它的返回值是IBinder*。而我们获取的IServiceManager的实际类型是BpServiceManager,它是继承自BpInterface,又继承自BpRefBase。因此我们实际是调用到了BpBinder.transact中了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
class BpRefBase : public virtual RefBase { protected: explicit BpRefBase(const sp<IBinder>& o); virtual ~BpRefBase(); virtual void onFirstRef(); virtual void onLastStrongRef(const void* id); virtual bool onIncStrongAttempted(uint32_t flags, const void* id); inline IBinder* remote() const { return mRemote; } inline sp<IBinder> remoteStrong() const { return sp<IBinder>::fromExisting(mRemote); }
private: BpRefBase(const BpRefBase& o); BpRefBase& operator=(const BpRefBase& o);
IBinder* const mRemote; RefBase::weakref_type* mRefs; std::atomic<int32_t> mState; };
|
在前面我们看过BpBinder的源码,它的transact实现实际是调用IPCThreadState的transact方法,所以只要是跨进程的逻辑,最终都是走到了IPCThreadState中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { status_t err; err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr); if ((flags & TF_ONE_WAY) == 0) { if (reply) { err = waitForResponse(reply); } else { Parcel fakeReply; err = waitForResponse(&fakeReply); } } else { err = waitForResponse(nullptr, nullptr); } return err; }
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer) { binder_transaction_data tr; .. mOut.writeInt32(cmd); mOut.write(&tr, sizeof(tr));
return NO_ERROR; }
|
接下来就进入到驱动了,驱动中会进行一系列的处理,这里也暂时先不去看。反正最后就会走到实体服务BnServiceManager的onTransact方法中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
::android::status_t BnServiceManager::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) { switch (_aidl_code) { ... case BnServiceManager::TRANSACTION_addService: { ... _aidl_ret_status = _aidl_data.readUtf8FromUtf16(&in_name); _aidl_ret_status = _aidl_data.readStrongBinder(&in_service); _aidl_ret_status = _aidl_data.readBool(&in_allowIsolated); _aidl_ret_status = _aidl_data.readInt32(&in_dumpPriority); ::android::binder::Status _aidl_status(addService(in_name, in_service, in_allowIsolated, in_dumpPriority)); _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); } ... } return _aidl_ret_status; }
|
最终是走到ServiceManager实体的addService方法来将服务添加到集合中,addService我们前面看到,就是将binder添加到它的ServiceMap中。同样的,查找服务的时候也是向上面的流程一样,BpServiceManager将所需要的数据写入到Parcel中,然后经由驱动中转,最终到达BnServiceManager中的onTransact:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
::android::status_t BnServiceManager::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) { switch (_aidl_code) { ... case BnServiceManager::TRANSACTION_getService: { _aidl_ret_status = _aidl_data.readUtf8FromUtf16(&in_name); ::android::binder::Status _aidl_status(getService(in_name, &_aidl_return)); _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); _aidl_ret_status = _aidl_reply->writeStrongBinder(_aidl_return); } ... } return _aidl_ret_status; }
|
最终走到ServiceManager实体的getService方法中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) { *outBinder = tryGetService(name, true); return Status::ok(); }
Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) { *outBinder = tryGetService(name, false); return Status::ok(); }
sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) { sp<IBinder> out; Service* service = nullptr; if (auto it = mNameToService.find(name); it != mNameToService.end()) { service = &(it->second); out = service->binder; } return out; }
|
注册服务和查找服务,都是一个跨进程的调用。我们看到在生成的AIDL代码中,在BpServiceManager中会自动将跨进程的方法包装成对应的code和data,然后进行快进程调用。而在BnServiceManager中会自动将数据进行解包判断,然后调用自身的方法,最终实现了跨进程的方法调用。
IInterface
至此,我们已经知道了Binder是什么了。它就是一个服务,一个可以跨越进程交互的服务。Binder的设计可以让我们以同步的方式实现跨进程的调用,它封装了具体的细节,让我们在使用的地方完全看不出来它是一个跨进程的调用。
那么服务又是什么呢?服务指的是注册在ServiceManager中的服务,可以说服务就是Binder。在前面我们看defaultServiceManager的时候,它是先获取到ServiceManager的BpBinder,然后通过interface_cast<AidlServiceManager>转成的BpServiceManager。如果获取的是BBinder的话,转换的结果就是BnServiceManager。这里之所以能够转换,就是因为IInterface。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
class IInterface : public virtual RefBase { public: IInterface(); static sp<IBinder> asBinder(const IInterface*); static sp<IBinder> asBinder(const sp<IInterface>&);
protected: virtual ~IInterface(); virtual IBinder* onAsBinder() = 0; };
template<typename INTERFACE> class BnInterface : public INTERFACE, public BBinder { public: virtual sp<IInterface> queryLocalInterface(const String16& _descriptor); virtual const String16& getInterfaceDescriptor() const;
protected: typedef INTERFACE BaseInterface; virtual IBinder* onAsBinder(); };
template<typename INTERFACE> class BpInterface : public INTERFACE, public BpRefBase { public: explicit BpInterface(const sp<IBinder>& remote);
protected: typedef INTERFACE BaseInterface; virtual IBinder* onAsBinder(); };
|

在前面我们获取到ServiceManager的IBinder后,就通过interface_cast转换成对应的ServiceManager了。因为BnServiceManager是继承自BBinder的,所以可以直接强转,而BpServiceManager与IBinder并没有直接的继承关系,因此是无法直接强转的。也就是说,interface_cast肯定不是简单的强转,而是有一定的逻辑在其中。
1 2 3 4 5 6 7
|
template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); }
|
其中interface_cast是定义在IInterface文件中的一个模板类方法,它的实现方法实际上是调用它指向的对象的asInterface方法,但是我们翻遍了所有的类和它的父类,都没有发现asInterface在哪定义的。再仔细看看实际是在IInterface中的一个宏中定义的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
#define DECLARE_META_INTERFACE(INTERFACE) \ public: \ static const ::android::String16 descriptor; \ static ::android::sp<I##INTERFACE> asInterface(const ::android::sp<::android::IBinder>& obj); \ virtual const ::android::String16& getInterfaceDescriptor() const; \ I##INTERFACE(); \ virtual ~I##INTERFACE(); \ static bool setDefaultImpl(::android::sp<I##INTERFACE> impl); \ static const ::android::sp<I##INTERFACE>& getDefaultImpl(); \ \ private: \ static ::android::sp<I##INTERFACE> default_impl; \ \ public:
|
它定义了一个descriptor属性以及一些方法,asInterface就是其中之一。同样的,它的实现部分也是在宏中定义的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ const ::android::StaticString16 I##INTERFACE##_descriptor_static_str16( \ __IINTF_CONCAT(u, NAME)); \ const ::android::String16 I##INTERFACE::descriptor(I##INTERFACE##_descriptor_static_str16); \ DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE0(I##INTERFACE, I##INTERFACE, Bp##INTERFACE)
#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE0(ITYPE, INAME, BPTYPE) \ const ::android::String16& ITYPE::getInterfaceDescriptor() const { return ITYPE::descriptor; } \ ::android::sp<ITYPE> ITYPE::asInterface(const ::android::sp<::android::IBinder>& obj) { \ ::android::sp<ITYPE> intr; \ if (obj != nullptr) { \ intr = ::android::sp<ITYPE>::cast(obj->queryLocalInterface(ITYPE::descriptor)); \ if (intr == nullptr) { \ intr = ::android::sp<BPTYPE>::make(obj); \ } \ } \ return intr; \ } \ ::android::sp<ITYPE> ITYPE::default_impl; \ bool ITYPE::setDefaultImpl(::android::sp<ITYPE> impl) { \ assert(!ITYPE::default_impl); \ if (impl) { \ ITYPE::default_impl = std::move(impl); \ return true; \ } \ return false; \ } \ const ::android::sp<ITYPE>& ITYPE::getDefaultImpl() { return ITYPE::default_impl; } \ ITYPE::INAME() {} \ ITYPE::~INAME() {}
|
实现逻辑就是先从IBinder中查询IInterface,查不到的时候表示当前的IBinder不是实体BBinder,而是一个BpBinder。因此直接创建对应的Bp类型的Service即可。其中,queryLocalInterface是定义在IBinder中的方法,但是在BnInterface中也定义了一次,也就是说我们实际调用的是BnInterface中的方法。
1 2 3 4 5 6 7 8 9 10
|
template<typename INTERFACE> inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface( const String16& _descriptor) { if (_descriptor == INTERFACE::descriptor) return sp<IInterface>::fromExisting(this); return nullptr; }
|
实际上interface_cast就是判断IBinder的类型,然后转换成Bn类型的服务或者Bp类型的服务。
定义一个服务
看了IInterface的实现以及相关的类,我们实际上已经可以模仿着AIDL的实现来实现自己的一个服务MyService了。
第一步,定义服务的接口,需要继承自IInterface,同时使用宏增加一些方法和实现:
1 2 3 4 5 6 7
| class IMyService : public IInterface { public: DECLARE_META_INTERFACE(MyService) virtual int demo() = 0; }
IMPLEMENT_META_INTERFACE(MyService, "com.demo.IMyService")
|
第二步,实现BnMyService:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class BnMyService : public BnInterface<IMyService> { public: static uint32_t TRANSACTION_demo = IBinder::FIRST_CALL_TRANSACTION + 0; int demo() { ALOGI("call from other process"); return 0; } status_t BnServiceManager::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { status_t result = 0; switch (code) { case BnMyService::TRANSACTION_demo: { if (!(data.checkInterface(this))) { result = BAD_TYPE; break; } demo() } default: result = BBinder::onTransact(code, data, reply, flags); } return result; }
|
第三步,实现BpMyService:
1 2 3 4 5 6 7 8 9 10 11
| class BpMyService : public BpInterface<IMyService> { public: int demo() { Parcel data; data.writeInterfaceToken(getInterfaceDescriptor()); Parcel reply; remote()->transact(BnMyService::TRANSACTION_demo, data, &reply, 0); return 0; } }
|