Android8.0.0-r4——Service代理对象的获取

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组件的代理对象返回给调用者。


代码路径:/frameworks/native/libs/binder/IServiceManager.cpp
(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}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值