本篇讲解系统服务的获取过程,即getService,其中addService过程参考Binder一文
MPS服务获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| IMediaDeathNotifier::getMediaPlayerService(){ sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder;
do { binder = sm->getService(String16("media.player")); if (binder != 0) { break; } ALOGW("Media player service not published, waiting..."); usleep(500000); } while (true); sMediaPlayerService = interface_cast<IMediaPlayerService>(binder); ...... return sMediaPlayerService; }
|
IServiceManager.h中的
- getService()
- checkService()
- addService()
都交给了IServiceManager.cpp中的内部类BpServiceManager来实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| virtual sp<IBinder> getService(const String16& name) const{ ...... while (uptimeMillis() < timeout) { ...... sp<IBinder> svc = checkService(name); if (svc != nullptr) return svc; } ...... }
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(); }
|
上面是MS进程,给Binder驱动发了消息
########################
Binder驱动
########################
SM进程循环监听Binder驱动是否有新消息,一旦有,就拿出来解析binder_parse
SM的binder_loop函数,在无限循环中不断的调用ioctl函数,它不断的使用BINDER_WRITE_READ指令查询Binder驱动中是否有 新的请求,如果有就交给binder_parse函数处理
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| int binder_parse(......){ ...... switch(cmd) { ...... case BR_TRANSACTION: { ...... res = func(bs, txn, &msg, &reply); ...... } ...... }
int svcmgr_handler(){ ...... switch(txn->code) { case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) { return -1; } handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid, (const char*) txn_secctx->secctx); if (!handle) break; bio_put_ref(reply, handle); return 0; ...... }
uint32_t do_find_service(......){ ...... struct svcinfo *si = find_svc(s, len); ...... return si->handle; ...... }
|