Service组件将自己注册到ServiceManager中之后, 它就在Server进程中等待Client进程将进程间通信请求发送过来。Client进程为了和运行在Server进程中的Service组件通信, 首先要获得它的一个代理对象, 这是通过ServiceManager提供的Service组件查询服务来实现的。
要获得Service的代理对象,首先要通过Binder驱动程序来获得一个引用了Service组件的Binder引用对象的句柄值, 然后再通过这个句柄值创建一个Binder代理对象, 即一个BpBinder对象, 最后将这个Binder代理对象封装成一个Service代理对象。
ServiceManager代理对象的成员函数get.Service提供了获取一个Service组件的代理对象的功能,而ServiceManager代理对象可以通过Binder库提供的函数defaultServiceManager 来获得。在调用ServiceManager代理对象的成员函数get.Service来获得一个Service组件的代理对象时, 需要指定这个Service组件注册到ServiceManager中的名称。
1、ServiceManager代理对象的获取
请参考:http://blog.csdn.net/nwpushuai/article/details/79491576
通过Binder库提供的函数defaultServiceManager 来获得ServiceManager代理对象
2、ServiceManager代理对象成员函数getService
代码路径:/frameworks/native/libs/binder/IServiceManager.cpp
(http://androidxref.com/8.0.0_r4/xref/frameworks/native/libs/binder/IServiceManager.cpp)
135 virtual sp<IBinder> getService(const String16& name) const 136 { 137 unsigned n; 138 for (n = 0; n < 5; n++){ 139 if (n > 0) { 140 if (!strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder")) { 141 ALOGI("Waiting for vendor service %s...", String8(name).string()); 142 CallStack stack(LOG_TAG); 143 } else { 144 ALOGI("Waiting for service %s...", String8(name).string()); 145 } 146 sleep(1); 147 } 148 sp<IBinder> svc = checkService(name); 149 if (svc != NULL) return svc; 150 } 151 return NULL; 152 }
这个函数最多会尝试5次来获得一个名称为name的Service组件的代理对象。如果上一次获得失败,那么146行就调用函数sleep使得当前线程睡眠1毫秒,然后再重新去获取;否则149行就直接将获得的Service组件的代理对象返回给调用者。
(http://androidxref.com/8.0.0_r4/xref/frameworks/native/libs/binder/IServiceManager.cpp)
153 154 virtual sp<IBinder> checkService( const String16& name) const 155 { 156 Parcel data, reply; 157 data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); 158 data.writeString16(name); 159 remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply); 160 return reply.readStrongBinder(); 161 }
ServiceManager代理对象的成员函数getService也是通过内部一个句柄值为0的Binder代理对象来与 ServiceManager通信的,请求ServiceManager执行一个CHECK_SERVICE_TRANSACTION操作。
ServiceManager是统一在函数svcmgr_handler中处理来自Client进程的进程间通信请求的,它处理操作代码为 CHECK_SERVICE_TRANSACTION的进程间通信请求的过程。
代码路径:/frameworks/native/cmds/servicemanager/service_manager.c
(http://androidxref.com/8.0.0_r4/xref/frameworks/native/cmds/servicemanager/service_manager.c)
252int svcmgr_handler(struct binder_state *bs, 253 struct binder_transaction_data *txn, 254 struct binder_io *msg, 255 struct binder_io *reply) 256{ 257 struct svcinfo *si; 258 uint16_t *s; 259 size_t len; 260 uint32_t handle; 261 uint32_t strict_policy; 262 int allow_isolated; 263 ................................................................... 297 switch(txn->code) { 298 case SVC_MGR_GET_SERVICE: 299 case SVC_MGR_CHECK_SERVICE: 300 s = bio_get_string16(msg, &len); 301 if (s == NULL) { 302 return -1; 303 } 304 handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid); 305 if (!handle) 306 break; 307 bio_put_ref(reply, handle); 308 return 0; .................................................................. 343 344 bio_put_uint32(reply, 0); 345 return 0; 346}
代码路径:/frameworks/native/cmds/servicemanager/service_manager.c
(http://androidxref.com/8.0.0_r4/xref/frameworks/native/cmds/servicemanager/service_manager.c)
178uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid) 179{ 180 struct svcinfo *si = find_svc(s, len); 181 182 if (!si || !si->handle) { 183 return 0; 184 } 185 186 if (!si->allow_isolated) { 187 // If this service doesn't allow access from isolated processes, 188 // then check the uid to see if it is isolated. 189 uid_t appid = uid % AID_USER; 190 if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) { 191 return 0; 192 } 193 } 194 195 if (!svc_can_find(s, len, spid, uid)) { 196 return 0; 197 } 198 199 return si->handle; 200}
180行调用函数find_svc来查找与字符串s对应的一个svcinfo结构体si
代码路径:/frameworks/native/cmds/servicemanager/binder.c
(http://androidxref.com/8.0.0_r4/xref/frameworks/native/cmds/servicemanager/binder.c)522void bio_put_ref(struct binder_io *bio, uint32_t handle) 523{ 524 struct flat_binder_object *obj; 525 526 if (handle) 527 obj = bio_alloc_obj(bio); 528 else 529 obj = bio_alloc(bio, sizeof(*obj)); 530 531 if (!obj) 532 return; 533 534 obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; 535 obj->type = BINDER_TYPE_HANDLE; 536 obj->handle = handle; 537 obj->cookie = 0; 538}