结合源码9、10、深入理解Android卷一
binder是Android系统提供的一种进程间通讯机制(IPC),Android系统可以看作是一个基于Binder通信的C/S框架
a、server进程要注册一些service到serviceManager中,所以server是serviceManager的客户端, serviceManager就是服务端
b、某个client要使用service,必须先到serviceManager中获取该service的相关信息,所以client是 serviceManager的客户端
c、client根据得到的service信息与service所在的server进程建立通信的通路,然后就可以直接与 service交互,client是service的客户端
d、三者的交互都是基于binder通信的
Binder只是为C/S架构提供了一种通信的方式




在defaultServiceManager中创建了BpBinder


最后还是回到interface_cast
在IServiceManager.h文件中,使用宏业务和通讯挂钩

宏定义在IInterface.h文件中
宏替换后的实际代码

DECLEAR宏声明了一些函数和一个变量
IMPLEMENT宏的作用就是定义
IMPLEMENT宏替换如下

interface_cast就是在IMPLEMTN宏中,将BpBinder指针转换成一个IServiceManager
intr = new BpServiceManager(obj)
- ::android::sp##INTERFACE> I##INTERFACE::asInterface( \
- const ::android::sp<::android::IBinder>& obj) \
- { \
- ::android::sp##INTERFACE> intr; \
- if (obj != nullptr) { \
- intr = static_cast##INTERFACE*>( \
- obj->queryLocalInterface( \
- I##INTERFACE::descriptor).get()); \
- if (intr == nullptr) { \
- intr = new Bp##INTERFACE(obj); //在这里做的转换 \
- } \
- } \
- return intr; \
- }
interface_cast不是指针的转换,而是利用BpBinder作为参数新建了一个BpServiceManager对象
回到IserviceManager

a、IServiceManager、BpServiceManager和BnServiceManager都与业务逻辑相关
b、BnServiceManager同时从IServiceManager BBinder派生,表示它可以直接参与Binder通讯
c、BpServiceManager从BpInterface派生,支线上看与BpBinder没有联系
d、BnServiceManager是一个虚类,业务最终需要子类来实现
BeRefBase中的mRemote就是BpBinder
IserviceManager中包含有BpServiceManager,在BpServiceManager继承自BpInterface

跟踪到BpRefBase

在构造函数中,mRemote(o.get())就是new BpBinder(0)
BpServiceManager的一个变量mRemote指向了BpBinder

defaultServiceManager有两个关键对象:
有一个BpBinder对象,它的handle的值是0
有一个BpServiceManager对象,它的mRemote值是BpBinder
BpServiceManager对象实现了IserviceManager的业务函数,又有BpBinder作为通信代表

MediaPlayerService注册,调用了defaultServiceManager的addService(),上面有分析到defaultServiceManager实际返回的对象是BpServiceManager
addService中

remote就是BpBinder
Parcel当作数据包
addService是一个业务层的函数,把请求数据打包成data后,传递给BpBinder的transact函数,就是把通信工作交给了BpBinder

在BpBinder的transact方法中,将数据直接交给了IPCThreadState的transact方法


第一次进入的时候gHaveTLS一定是false
注:TLS是Thread Local Storage线程本地存储空间的简称,这种空间每个线程都有,线程间不会共享
会new一个IPCThreadState对象,构造函数中会调用pthread_setspecific

pthread_setspecific把自己设置到线程本地存储中去
mIn和mOut是两个Parcel,发送和接收命令的缓冲区
每个线程都有一个IPCThreadState,每个IPCThreadState中都有一个mIn,mOut,mIn是用来接收来自Binder设备的数据,mOut是用来存储发往Binder设备的数据

再到IPCThreadState的transact,这个函数实际完成了与Binder通信的工作

先发数据,再等结果
先看发送方法writeTransactionData

binder_transaction_data是和binder设备通信的数据结构
code是消息码
mOut将命令写入,但没有发送出去,到这里,将addService的请求信息已经写到mOut中

等待回复waitForResponse

收到回复后的处理executeCommand(cmd)
- case BR_TRANSACTION:
- {
- binder_transaction_data_secctx tr_secctx;
- binder_transaction_data& tr = tr_secctx.transaction_data;
-
- if (cmd == (int) BR_TRANSACTION_SEC_CTX) {
- result = mIn.read(&tr_secctx, sizeof(tr_secctx));
- } else {
- result = mIn.read(&tr, sizeof(tr));
- tr_secctx.secctx = 0;
- }
-
- ALOG_ASSERT(result == NO_ERROR,
- "Not enough command data for brTRANSACTION");
- if (result != NO_ERROR) break;
-
- //Record the fact that we're in a binder call.
- mIPCThreadStateBase->pushCurrentState(
- IPCThreadStateBase::CallState::BINDER);
- Parcel buffer;
- buffer.ipcSetDataReference(
- reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
- tr.data_size,
- reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
- tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
-
- const pid_t origPid = mCallingPid;
- const char* origSid = mCallingSid;
- const uid_t origUid = mCallingUid;
- const int32_t origStrictModePolicy = mStrictModePolicy;
- const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
- const int32_t origWorkSource = mWorkSource;
- const bool origPropagateWorkSet = mPropagateWorkSource;
- // Calling work source will be set by Parcel#enforceInterface. Parcel#enforceInterface
- // is only guaranteed to be called for AIDL-generated stubs so we reset the work source
- // here to never propagate it.
- clearCallingWorkSource();
- clearPropagateWorkSource();
-
- mCallingPid = tr.sender_pid;
- mCallingSid = reinterpret_cast<const char*>(tr_secctx.secctx);
- mCallingUid = tr.sender_euid;
- mLastTransactionBinderFlags = tr.flags;
-
- // ALOGI(">>>> TRANSACT from pid %d sid %s uid %d\n", mCallingPid,
- // (mCallingSid ? mCallingSid : "
"), mCallingUid); -
- Parcel reply;
- status_t error;
- IF_LOG_TRANSACTIONS() {
- TextOutput::Bundle _b(alog);
- alog << "BR_TRANSACTION thr " << (void*)pthread_self()
- << " / obj " << tr.target.ptr << " / code "
- << TypeCode(tr.code) << ": " << indent << buffer
- << dedent << endl
- << "Data addr = "
- << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
- << ", offsets addr="
- << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
- }
- if (tr.target.ptr) {
- // We only have a weak reference on the target object, so we must first try to
- // safely acquire a strong reference before doing anything else with it.
- if (reinterpret_cast
( - tr.target.ptr)->attemptIncStrong(this)) {
- error = reinterpret_cast
(tr.cookie)->transact(tr.code, buffer, - &reply, tr.flags);
- reinterpret_cast
(tr.cookie)->decStrong(this); - } else {
- error = UNKNOWN_TRANSACTION;
- }
-
- } else {
- error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
- }
-
- mIPCThreadStateBase->popCurrentState();
- //ALOGI("<<<< TRANSACT from pid %d restore pid %d sid %s uid %d\n",
- // mCallingPid, origPid, (origSid ? origSid : "
"), origUid); -
- if ((tr.flags & TF_ONE_WAY) == 0) {
- LOG_ONEWAY("Sending reply to %d!", mCallingPid);
- if (error < NO_ERROR) reply.setError(error);
- sendReply(reply, 0);
- } else {
- LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
- }
-
- mCallingPid = origPid;
- mCallingSid = origSid;
- mCallingUid = origUid;
- mStrictModePolicy = origStrictModePolicy;
- mLastTransactionBinderFlags = origTransactionBinderFlags;
- mWorkSource = origWorkSource;
- mPropagateWorkSource = origPropagateWorkSet;
-
- IF_LOG_TRANSACTIONS() {
- TextOutput::Bundle _b(alog);
- alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
- << tr.target.ptr << ": " << indent << reply << dedent << endl;
- }
-
- }
- break;
the_context_object是IPCThreadState.cpp中定义的一个全局变量
可通过setTheContextObject函数设置

收到binder驱动发来的service死掉的消息

这里收到来自驱动的指示,创建一个新的线程,用于和binder通信

talkWithDriver()

startThreadPool()

如果已经mThreadPoolStarted,函数没有下一步
调用spawnPooledThread(true)

在PoolThread中创建一个IPCThreadState,每个线程都有一个,但线程不共享,调用joinThreadPool(true)

来到joinThreadPool(true)

isMain为true,需要循环处理,把请求信息写到mOut中,后续会发送出去
getAndExecuteCommand处理消息
组装请求信息到mOut中,最后调用talkWithDriver(false)

有两个线程在为service服务:
startThreadPool中新启动的线程通过joinThreadPool读取Binder设备,查看是否有请求
主线程也调用joinThreadPool读取binder设备,查看是否有请求
Binder设备是支持多线程操作的
Binder是通信机制,业务可以基于Binder通信,也可以使用别的IPC通信

defultServiceManager返回的是一个BpServiceManager,通过它可以把命令请求发送给handle值为0的目的端

应该有一个类从BnServiceManager中派生出来,并处理来自远方的请求,源码中并没有,是ServiceManager完成了BnServiceManager的工作
篇幅有限,下篇继续