Android系统进程间通信(IPC)机制Binder中的Client获(3)

在BpServiceManager::checkService中,首先是通过Parcel::writeInterfaceToken往data写入一个RPC头,这个我们在Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析一文已经介绍过了,就是写往data里面写入了一个整数和一个字符串“Android.os.IServiceManager”, Service Manager来处理CHECK_SERVICE_TRANSACTION请求之前,会先验证一下这个RPC头,看看是否正确。接着再往data写入一个字符串name,这里就是“media.player”了。回忆一下Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析这篇文章,那里已经往Service Manager中注册了一个名字为“media.player”的MediaPlayerService。

这里的remote()返回的是一个BpBinder,具体可以参考浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路一文,于是,就进行到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;   }  

这里的mHandle = 0,code = CHECK_SERVICE_TRANSACTION,flags = 0。

这里再进入到IPCThread::transact函数中:

status_t IPCThreadState::transact(int32_t handle,                                     uint32_t code, const Parcel& data,                                     Parcel* reply, uint32_t flags)   {       status_t err = data.errorCheck();          flags |= TF_ACCEPT_FDS;          IF_LOG_TRANSACTIONS() {           TextOutput::Bundle _b(alog);           alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "               << handle << " / code " << TypeCode(code) << ": "               << indent << data << dedent << endl;       }              if (err == NO_ERROR) {           LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),               (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");           err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);       }              if (err != NO_ERROR) {           if (reply) reply->setError(err);           return (mLastError = err);       }              if ((flags & TF_ONE_WAY) == 0) {           #if 0            if (code == 4) { // relayout                LOGI(">>>>>> CALLING transaction 4");           } else {               LOGI(">>>>>> CALLING transaction %d", code);           }           #endif            if (reply) {               err = waitForResponse(reply);           } else {               Parcel fakeReply;               err = waitForResponse(&fakeReply);           }           #if 0            if (code == 4) { // relayout                LOGI("<<<<<< RETURNING transaction 4");           } else {               LOGI("<<<<<< RETURNING transaction %d", code);           }           #endif                       IF_LOG_TRANSACTIONS() {               TextOutput::Bundle _b(alog);               alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "                   << handle << ": ";               if (reply) alog << indent << *reply << dedent << endl;               else alog << "(none requested)" << endl;           }       } else {           err = waitForResponse(NULL, NULL);       }              return err;   }  

首先是调用函数writeTransactionData写入将要传输的数据到IPCThreadState的成员变量mOut中去:

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;          tr.target.handle = handle;       tr.code = code;       tr.flags = binderFlags;              const status_t err = data.errorCheck();       if (err == NO_ERROR) {           tr.data_size = data.ipcDataSize();           tr.data.ptr.buffer = data.ipcData();           tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);           tr.data.ptr.offsets = data.ipcObjects();       } else if (statusBuffer) {           tr.flags |= TF_STATUS_CODE;           *statusBuffer = err;           tr.data_size = sizeof(status_t);           tr.data.ptr.buffer = statusBuffer;           tr.offsets_size = 0;           tr.data.ptr.offsets = NULL;       } else {           return (mLastError = err);       }              mOut.writeInt32(cmd);       mOut.write(&tr, sizeof(tr));              return NO_ERROR;   }  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwjjgs.html