1、参数说明: code 是请求的ID号。 data 是请求的参数。 reply 是返回的结果。 flags 一些额外的标识,如FLAG_ONEWAY。通常为0。transact只是简单的调用了IPCThreadState:self()的transact,在IPCThreadState:transact中:status_t IPCThreadState:transact(int32_t handle, data, Parcel* reply, uint32_t flags) status_t err = data.errorCheck(); flags |= TF_ACCEPT_FDS; IF_L
2、OG_TRANSACTIONS() TextOutput:Bundle _b(alog); alog BC_TRANSACTION thr (void*)pthread_self() / hand handle / code TypeCode(code) indent data dedent SEND from pid %d uid %d %s, getpid(), getuid(), (flags & TF_ONE_WAY) = 0 ?READ REPLY :ONE WAY); err = writeTransactionData(BC_TRANSACTION, flags, handle,
3、 code, data, NULL); if (err != NO_ERROR) if (reply) reply-setError(err); return (mLastError = err); if (flags & TF_ONE_WAY) = 0) if (reply) err = waitForResponse(reply); else Parcel fakeReply; err = waitForResponse(&fakeReply);BR_REPLY thr ; if (reply) alog *reply else alog (none requested) err = wa
4、itForResponse(NULL, NULL); return err;waitForResponse(Parcel *reply, status_t *acquireResult) int32_t cmd; int32_t err; while (1) if (err=talkWithDriver() NO_ERROR) break; err = mIn.errorCheck(); if (err if (mIn.dataAvail() = 0) continue; cmd = mIn.readInt32(); IF_LOG_COMMANDS() Processing waitForRe
5、sponse Command: getReturnString(cmd) ipcSetDataReference( reinterpret_cast(tr.data.ptr.buffer), tr.data_size, reinterpret_cast(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), freeBuffer, this); err = *static_cast(tr.data.ptr.buffer); freeBuffer(NULL, tr.offsets_size/sizeof(size_t), this); cont
6、inue; default: err = executeCommand(cmd);finish: if (acquireResult) *acquireResult = err; mLastError = err;这里transact把请求经内核模块发送了给服务端,服务端处理完请求之后,沿原路返回结果给调用者。这里也可以看出请求是同步操作,它会等待直到结果返回为止。在BpBinder之上进行简单包装,我们可以得到与服务对象相同的接口,调用者无需要关心调用的对象是远程的还是本地的。拿ServiceManager来说:(frameworks/base/libs/utils/IServiceMana
7、ger.cpp)class BpServiceManager : public BpInterfacepublic: BpServiceManager(const sp& impl) BpInterface(impl). virtual status_t addService(const String16& name, const sp& service) Parcel data, reply; data.writeInterfaceToken(IServiceManager:getInterfaceDescriptor(); data.writeString16(name); data.wr
8、iteStrongBinder(service); status_t err = remote()-transact(ADD_SERVICE_TRANSACTION, data, &reply); return err = NO_ERROR ? reply.readInt32() : err;BpServiceManager实现了 IServiceManager和IBinder两个接口,调用者可以把BpServiceManager的对象看作是一个 IServiceManager对象或者IBinder对象。当调用者把BpServiceManager对象当作IServiceManager对象使用时
9、,所有的请求只是对BpBinder:transact的封装。这样的封装使得调用者不需要关心IServiceManager对象是本地的还是远程的了。客户通过defaultServiceManager函数来创建BpServiceManager对象:sp defaultServiceManager() if (gDefaultServiceManager != NULL) return gDefaultServiceManager; AutoMutex _l(gDefaultServiceManagerLock); if (gDefaultServiceManager = NULL) gDefaul
10、tServiceManager = interface_castgetStrongProxyForHandle(int32_t handle) spbinder; if (b = NULL | !e-refs-attemptIncWeak(this) b = new BpBinder(handle); e-binder = b; if (b) e-refs = b-getWeakRefs(); result = b; / This little bit of nastyness is to allow us to add a primary / reference to the remote
11、proxy when this team doesnt have one / but another team is sending the handle to us. result.force_set(b);decWeak(this); return result;如果handle为空,默认为context_manager对象,context_manager实际上就是ServiceManager。o 服务端服务端也要实现IBinder接口,BBinder类对IBinder接口提供了部分默认实现,其中transact的实现如下:status_t BBinder: data.setDataPos
12、ition(0); status_t err = NO_ERROR; switch (code) case PING_TRANSACTION:writeInt32(pingBinder(); err = onTransact(code, data, reply, flags); if (reply !setDataPosition(0);PING_TRANSACTION请求用来检查对象是否还存在,这里简单的把 pingBinder的返回值返回给调用者。其它的请求交给onTransact处理。onTransact是BBinder里声明的一个 protected类型的虚函数,这个要求它的子类去实现
13、。比如CameraService里的实现如下:status_t CameraService:onTransact( / permission checks. case BnCameraService:CONNECT: IPCThreadState* ipc = IPCThreadState:self(); const int pid = ipc-getCallingPid(); const int self_pid = getpid(); if (pid != self_pid) / were called from a different process, do the real check
14、checkCallingPermission( String16(android.permission.CAMERA) const int uid = ipc-getCallingUid(); LOGE(Permission Denial:cant use the camera pid=%d, uid=%d, pid, uid); return PERMISSION_DENIED; status_t err = BnCameraService:onTransact(code, data, reply, flags); LOGD(+ onTransact err %d code %d, err,
15、 code); if (err = UNKNOWN_TRANSACTION | err = PERMISSION_DENIED) / the service command interrogates this binder for its name, and then supplies it / even for the debugging commands. that means we need to check for it here, using / ISurfaceComposer (since we delegated the INTERFACE_TRANSACTION handli
16、ng to / BnSurfaceComposer before falling through to this code).+ onTransact code %d, code); CHECK_INTERFACE(ICameraService, data, reply); switch(code) case 1000: if (gWeakHeap != 0) sp h = gWeakHeap.promote(); IMemoryHeap *p = gWeakHeap.unsafe_get();CHECKING WEAK REFERENCE %p (%p), h.get(), p); if (
17、h != 0) h-printRefs(); bool attempt_to_delete = data.readInt32() = 1; if (attempt_to_delete) / NOT SAFE!DELETING WEAK REFERENCE %p (%p) if (p) delete p; return NO_ERROR;由此可见,服务端的onTransact是一个请求分发函数,它根据请求码(code)做相应的处理。o 消息循环服务端(任何进程都可以作为服务端)有一个线程监听来自客户端的请求,并循环处理这些请求。如果在主线程中处理请求,可以直接调用下面的函数:IPCThreadS
18、tate:joinThreadPool(mIsMain);如果想在非主线程中处理请求,可以按下列方式: sp proc = ProcessState: if (proc-supportsProcesses() LOGV(App process: starting thread pool./n proc-startThreadPool();startThreadPool的实现原理:void ProcessState:startThreadPool()mThreadPoolStarted) mThreadPoolStarted = true; spawnPooledThread(true);spawnPooledThread(bool isMain) if (mThreadPoolStarted) int32_t s = android_atomic_add(1, &mThreadPoolSeq); char buf32; sprintf(buf, Binder Thread #%d, s);Spawning new
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1