场景:
1)IMediaPlayer.cpp
Bn -> Bp
sp<IGraphicBufferProducer> bufferProducer =
interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
reply->writeInt32(setVideoSurfaceTexture(bufferProducer));
在mediaplayerservice中使用
sp<IGraphicBufferProducer>& bufferProducer 该Bp 与Bn 交互
2) 将mediaplayerservice进程中该Bp对象传递给另外一个进程中使用
virtual status_t connect(const sp<IGraphicBufferProducer> &bufferProduce, sp<IRemoteDisplayClient> &sinkClient)
{
Parcel data, reply;
data.writeInterfaceToken(IRemoteDisplay::getInterfaceDescriptor());
data.writeStrongBinder(IInterface::asBinder(bufferProduce));
data.writeStrongBinder(IInterface::asBinder(sinkClient));
remote()->transact(CONNECT, data, &reply);
return reply.readInt32();
}
status_t BnRemoteDisplay::onTransact(..........){.........
case CONNECT:{
CHECK_INTERFACE(IRemoteDisplay, data, reply);
sp<IGraphicBufferProducer> bufferproducer = IGraphicBufferProducer::asInterface(data.readStrongBinder()); //从mediaplayerservice进程中获取到的Bp对象在这边也可以被使用
sp<IRemoteDisplayClient> clientsink = interface_cast<IRemoteDisplayClient>(data.readStrongBinder());
reply->writeInt32(connect(bufferproducer,clientsink));
return NO_ERROR;
}
3) 一个BnXX 可以被多个类继承,然后在不同接口处 得到的Bp
return interface_cast<IRemoteDisplay>(reply.readStrongBinder());
自身能够区分出来对应是哪个类的Bn
<IRemoteDisplay> 与RemoteDisplay 不是一一对应, IRemoteDisplay 可能对应多个类
4)
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();
if (!local) {
BpBinder *proxy = real->remoteBinder();
if (proxy == NULL) {
ALOGE("null proxy");
}
const int32_t handle = proxy ? proxy->handle() : 0;
obj.type = BINDER_TYPE_WEAK_HANDLE;
obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
obj.handle = handle;
obj.cookie = 0;
} else {
obj.type = BINDER_TYPE_WEAK_BINDER;
obj.binder = reinterpret_cast<uintptr_t>(binder.get_refs());
obj.cookie = reinterpret_cast<uintptr_t>(binder.unsafe_get());
}
return finish_flatten_binder(real, obj, out);
}
flat_binder_object写入到Parcel类中,再调用 IPCThreadState::transact将Parcel数据填充binder_transaction_data数据结构,将此数据结构写入内 核
status_t Parcel::readStrongBinder(sp<IBinder>* val) const
{
return unflatten_binder(ProcessState::self(), *this, 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 = reinterpret_cast<IBinder*>(flat->cookie);
return finish_unflatten_binder(NULL, *flat, in);
case BINDER_TYPE_WEAK_BINDER:
if (flat->binder != 0) {
out->set_object_and_refs(
reinterpret_cast<IBinder*>(flat->cookie),
reinterpret_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);根据handle创建Binder
return finish_unflatten_binder(
static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
}
}
frameworks/native/libs/binder/ProcessState.cpp
wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
{
wp<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. The
// attemptIncWeak() is safe because we know the BpBinder destructor will always
// call expungeHandle(), which acquires the same lock we are holding now.
// We need to do this because there is a race condition between someone
// releasing a reference on this BpBinder, and a new reference on its handle
// arriving from the driver.
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
b = new BpBinder(handle);//重新创建的一个Bp
result = b;
e->binder = b;
if (b) e->refs = b->getWeakRefs();
} else {
result = b;
e->refs->decWeak(this);
}
}
return result;
}
转载于:https://blog.51cto.com/lindt/1902637