在Binder: ServiceManager的获取文章中,分析了ProcessState
与IPCThreadState
的创建过程。最后在defaultServiceManager
中,返回的是持有BpBinder
的BpServiceManager
对象。
int main(int argc __unused, char **argv __unused)
{
signal(SIGPIPE, SIG_IGN);
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager()); // BpServiceManager
ALOGI("ServiceManager: %p", sm.get());
AIcu_initializeIcuOrDie();
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
registerExtensions();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
所以在instantiate
方法中调用的addService
其实是BpServiceManager
中的方法,将名称为media.player
的MediaPlayerService
对象进行注册
addService
下面我们直接看BpServiceManager
中的addService
。
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated, int dumpsysPriority) {
// 封装成Parcel对象
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
data.writeInt32(dumpsysPriority);
// 发送数据到远端
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
这里将数据统一封装到Parcel
对象中,最后通过remote()
的transact
方法将数据传输到远端,对应的code
为ADD_SERVICE_TRANSACTION
。
现在我们在来看下remote()
到底是什么。
它是BpServiceManager
中的一个方法,这个方法来自于它的父类
class BpServiceManager : public BpInterface<IServiceManager>
public:
explicit BpServiceManager(const sp<IBinder>& impl) // BpBinder(0)
: BpInterface<IServiceManager>(impl) {}
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) : BpRefBase(remote)
BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()), mRefs(nullptr), mState(0)
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() { return mRemote; }
inline IBinder* remote() const { return mRemote; }
private:
BpRefBase(const BpRefBase& o);
BpRefBase& operator=(const BpRefBase& o);
IBinder* const mRemote;
RefBase::weakref_type* mRefs;
std::atomic<int32_t> mState;
};
从上面继承流程可以得到这个remote()
返回的就是mRemote
,而mRemote
其实是最开始的参数BpBinder(0)
。说明这里调用的是BpBinder
的transact
方法
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
进入BpBinder
发现又转调到IPCThreadState
的transact
方法
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
...
// 传输数据
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;
}
这里主要做的就两件事
- 通过
writeTransactionData
将数据写入到Parcel
中,对应的cmd
命令为BC_TRANSACTION
,这是请求码,对应的都是以BC_
开头命名,在service
端会通过这些请求码做不同的逻辑处理。 - 通过
waitForResponse
来等待远端的数据返回,这里也有一个cmd
命令行,例如BR_REPLY
,这是返回码,对应的都是以BR_
开头命名的,在client
也会通过这些返回码做不同的逻辑处理。
今天我们不研究这几个方法,后续文章会专门分析数据的交互。
到这里MediaPlayerService
已经注册完毕,我们接下最前面的main
方法继续往下走。
startThreadPool
代码语言:javascript复制ProcessState::self()->startThreadPool();
又是ProcessState
中的方法,进入startThreadPooll
中看一下。
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
// 开启binder线程池
sp<Thread> t = new PoolThread(isMain);
t->run(name.string());
}
}
在spawnPooledThread
方法中创建了PoolThread
线程池,它继承于Thread
,最后调用了线程的run
方法
joinThreadPool
代码语言:javascript复制IPCThreadState::self()->joinThreadPool();
继续看joinThreadPooll
方法, 它在IPCThreadState
中
void IPCThreadState::joinThreadPool(bool isMain)
{
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t result;
do {
processPendingDerefs();
// 等待命令行的到来
result = getAndExecuteCommand();
} while (result != -ECONNREFUSED && result != -EBADF);
mOut.writeInt32(BC_EXIT_LOOPER);
// 与binder驱动通信
talkWithDriver(false);
}
这里主要的方法是getAndExecuteCommand()
,它是用来处理接收service
端发送过来的数据,因为service
与client
是可以互相发起数据的交互。这个时候client
就相当于service
,它开启轮询不断地监听service
发过来的数据。最终它会调用executeCommand
来统一处理。
status_t IPCThreadState::executeCommand(int32_t cmd)
{
switch ((uint32_t)cmd) {
...
case BR_TRANSACTION_SEC_CTX:
case BR_TRANSACTION:
{
...
if (tr.target.ptr) {
if (reinterpret_cast<RefBase::weakref_type*>(
tr.target.ptr)->attemptIncStrong(this)) {
// BBinder
error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
&reply, tr.flags);
reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
} else {
error = UNKNOWN_TRANSACTION;
}
} else {
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
...
if ((tr.flags & TF_ONE_WAY) == 0) {
// 向服务端发送回应reply,注意这里的0,特定标识;
sendReply(reply, 0);
} else {
LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
}
...
}
break;
...
default:
ALOGE("*** BAD COMMAND %d received from Binder drivern", cmd);
result = UNKNOWN_ERROR;
break;
}
if (result != NO_ERROR) {
mLastError = result;
}
return result;
}
为了简化代码只展示了主要的一部分代码,BR_TRANSACTION
类似于上面所说的BC_TRANSACTION
,这里代表的是从服务端有数据发送过来,说明服务端主动传输数据。
所以这个时候就与service
端建立了通信。
至此在client
端的数据交互流程已经分析完毕,后续我们再来看binder
传输过程中的service
端,看它是如何接收与处理数据的。