sm->getService(String16("media.player"))
昨天分析到这里,始终没有搞清楚getService这个函数到底是怎么获取到对应的服务的,具体只有下面两行代码:
sp<IServiceManager> sm = defaultServiceManager();
binder = sm->getService(String16("media.player"));
defaultServiceManager()这个函数调用已经清楚了,所以第一行的调用基本可以等价于以下代码(去除了进程线程对象唯一等等):
sp<IServiceManager> sm = new BpServiceManager(new BpBinder(0));
所以sm 就是一个BpServiceManager对象,通过BpBinder对象与Binder驱动对话,唤醒ServiceManager进程,再获得ServiceManager的返回,主要是在返回后没有理解,到达的代码如下:
status_t IPCThreadState::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 < NO_ERROR) break; if (mIn.dataAvail() == 0) continue;
cmd = mIn.readInt32();
IF_LOG_COMMANDS() { alog << "Processing waitForResponse Command: " << getReturnString(cmd) << endl; }
switch (cmd) { … case BR_REPLY: { binder_transaction_data tr; err = mIn.read(&tr, sizeof(tr)); ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY"); if (err != NO_ERROR) goto finish;
if (reply) { if ((tr.flags & TF_STATUS_CODE) == 0) { reply->ipcSetDataReference( reinterpret_cast<const uint8_t*>(tr.dataNaNr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.dataNaNr.offsets), tr.offsets_size/sizeof(size_t), freeBuffer, this); } else { err = *static_cast<const status_t*>(tr.dataNaNr.buffer); freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.dataNaNr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.dataNaNr.offsets), tr.offsets_size/sizeof(size_t), this); } } else { freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.dataNaNr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.dataNaNr.offsets), tr.offsets_size/sizeof(size_t), this); continue; } } goto finish;
default: err = executeCommand(cmd); if (err != NO_ERROR) goto finish; break; } } |
这里的reply返回后会一直传到以下代码:
/*\frameworks\native\libs\binder\IServiceManager.cpp*/
class BpServiceManager : public BpInterface<IServiceManager> { public: BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(impl) { }
virtual sp<IBinder> getService(const String16& name) const { unsigned n; for (n = 0; n < 5; n++){ sp<IBinder> svc = checkService(name); if (svc != NULL) return svc; ALOGI("Waiting for service %s...\n", String8(name).string()); sleep(1); } return NULL; }
virtual sp<IBinder> checkService( const String16& name) const { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name); remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply); return reply.readStrongBinder(); } |
进入Parcel看看reply.readStrongBinder();:
sp<IBinder> Parcel::readStrongBinder() const { sp<IBinder> val; unflatten_binder(ProcessState::self(), *this, &val); return val; }
status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, wp<IBinder>* out) { const flat_binder_object* flat = in.readObject(false);
if (flat) { switch (flat->type) { case BINDER_TYPE_BINDER: *out = static_cast<IBinder*>(flat->cookie); return finish_unflatten_binder(NULL, *flat, in); case BINDER_TYPE_WEAK_BINDER: if (flat->binder != NULL) { out->set_object_and_refs( static_cast<IBinder*>(flat->cookie), static_cast<RefBase::weakref_type*>(flat->binder)); } else { *out = NULL; } return finish_unflatten_binder(NULL, *flat, in); case BINDER_TYPE_HANDLE: case BINDER_TYPE_WEAK_HANDLE: *out = proc->getWeakProxyForHandle(flat->handle); return finish_unflatten_binder( static_cast<BpBinder*>(out->unsafe_get()), *flat, in); } } return BAD_TYPE; } |
这里flat->type是BINDER_TYPE_HANDLE,所以调用ProcessState::getStrongProxyForHandle()函数,这里的handle就是ServiceManager内维护的MediaPlayerService对应的Binder句柄,这个ProcessState根据这个句柄new 了一个BpBinder,并将其保存起来,这样下次需要从ServiceManager请求获取到相同句柄的时候就可以直接返回了。
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) { // We need to create a new BpBinder if there isn't currently one, OR we // are unable to acquire a weak reference on this current one. See comment // in getWeakProxyForHandle() for more info about this. IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { if (handle == 0) { Parcel data; status_t status = IPCThreadState::self()->transact( 0, IBinder::PING_TRANSACTION, data, NULL, 0); if (status == DEAD_OBJECT) return NULL; }
b = new BpBinder(handle); à这里的handle不为0,而是MediaPlayerService在ServiceManager中对应的句柄 e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } else { // This little bit of nastyness is to allow us to add a primary // reference to the remote proxy when this team doesn't have one // but another team is sending the handle to us. result.force_set(b); e->refs->decWeak(this); } }
return result; } |
根据这个返回的BpBinder获得MediaPlayerService的代理:
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
根据前面ServiceManager一样,最后调用的是IMediaPlayerService的asInterface()宏函数,等价于以下:
android::sp<IMediaPlayerService> IMediaPlayerService::asInterface(const android::sp<android::IBinder>& obj) { android::sp<IMediaPlayerService> intr; if(obj != NULL ) { intr = static_cast<IMediaPlayerService>( obj->queryLocalInterface(IMediaPlayerService::descriptor).get); if (intr == NULL) { intr = new BpMediaPlayerService(obj); } } return intr; } |
sm->getService(String16("media.player"));整个过程就相当于与ServiceManager进程对话,查找相关的服务对应的handle值,再创建一个新BpBinder对象,构造对应服务的Bp对象。