binder机制关于匿名service,handle是如何赋值的

3 篇文章 0 订阅

以媒体服务为例。

我们从java层开始查看关于binder通信的代码,往下搜索始终都是new BpBinder(0),这里的handle始终是0。难道所以的service都是通过BpBinder(0)来发送消息的吗?

那就失去了binder通信建立那么多I***的意义了。

我们经常在代码里面看到类似的语句

data.writeStrongBinder(connection.asBinder()); 

或者 IBinder binder = reply.readStrongBinder(); 类似的接口。

我们看看这里面到底发生了什么。

在writeStrongBinder函数里面藏了一个秘密,我们一块来看看writeStrongBinder的代码。

status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
    return flatten_binder(ProcessState::self(), val, this);
}


status_t flatten_binder(const sp<ProcessState>& proc,
    const wp<IBinder>& binder, Parcel* out)
{
    flat_binder_object obj;
    
    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    if (binder != NULL) {
        sp<IBinder> real = binder.promote();
        if (real != NULL) {
            IBinder *local = real->localBinder(); //这里返回的是一个BBinder的实例, 查看binder.cpp里面实现的BBinder
            if (!local) {
                BpBinder *proxy = real->remoteBinder(); //proxy是BpBinder实例
                if (proxy == NULL) {
                    LOGE("null proxy");
                }
                const int32_t handle = proxy ? proxy->handle() : 0;   //这里这个handle应该就是我们想要看的那个handle。如果这个代理类不为空,那么就是这个代理类的handle,否则就是0.
                obj.type = BINDER_TYPE_WEAK_HANDLE;
                obj.handle = handle;
                obj.cookie = NULL;
            } else {
                obj.type = BINDER_TYPE_WEAK_BINDER;
                obj.binder = binder.get_refs();
                obj.cookie = binder.unsafe_get();
            }
            return finish_flatten_binder(real, obj, out);
        }
        
        // XXX How to deal?  In order to flatten the given binder,
        // we need to probe it for information, which requires a primary
        // reference...  but we don't have one.
        //
        // The OpenBinder implementation uses a dynamic_cast<> here,
        // but we can't do that with the different reference counting
        // implementation we are using.
        LOGE("Unable to unflatten Binder weak reference!");
        obj.type = BINDER_TYPE_BINDER;
        obj.binder = NULL;
        obj.cookie = NULL;
        return finish_flatten_binder(NULL, obj, out);
    
    } else {
        obj.type = BINDER_TYPE_BINDER;
        obj.binder = NULL;
        obj.cookie = NULL;
        return finish_flatten_binder(NULL, obj, out);
    }
}


还以为这里面有什么秘密,以为在这里对这个handle进行了处理。可是查看kernel binder.c代码并没有对这个handle进行处理,只有这个地方了。难道理解错了吗?

我们从获取一个service顺着一个service往下找。以MediaPlayer.cpp为例,

setDataSource

这里调用了getMediaPlayerService(),获得了一个BpMediaPlayerService的服务。

在获取这个服务的时候

首先,我们获得了一个BpServiceManager,使用这个BpServiceManager和底层BnServiceManger进行对话,获得这个服务。

在BpServiceManager里面 getService调用了checkService,在这里面返回了reply.readStrongBinder();这样的一个调用。

我们先顺着往下看。在BnServiceManager端,CHECK_SERVICE_TRANSACTION,这个服务在ServiceManager里面进行了注册,是可以找到的。

这里获得了一个BnMediaPlayerService的对象。通过reply->writeStrongBinder(b);传递到Bp端。

我们知道现在Bp端的对象没有创建,所以这个handle还是没有进行设置。proxy 是空的,handle默认是0.

看了看kernel的代码,里面对这个proxy已经赋值了,并且对这个handle进行了赋值。

我们就认为在writeStrongBinder() 已经有handle值。那就能和相应的BBinder以及BpXXX对应上了





  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值