05.Binder系统:第7课第4节_Binder系统_c++实现_内部机制_代理类BpXXX分析

在binder系统中,其主要涉及三个应用程序,以我们之前编写的C++程序为例,分别为test_server,test_client,ServiceManageer。

其中test_client通过代理类BpHelloService与test_server进行通信,在最初阶段,test_server会通过addservice向ServiceManageer添加服务,test_server与ServiceManageer的通信时通过BpServiceManageer。test_client使用getSsrvice获取服务的时候,也是是通过BpServiceManageer进行通信。

BpServiceManageer其中的handle==0,BpHelloService中的handle是通过BpServiceManageer.getService(“hello”)获得。在我们实验中,其为1。在上面提到的两个代理类,.BpServiceManageer与BpHelloService是非常相似的。其他们的各类继承关系如夏图所示:
在这里插入图片描述
打开test_server.cpp,与test_client.cpp我们可以在其中找到

	/* 获得BpServiceManager */
	sp<IServiceManager> sm = defaultServiceManager();

进入IServiceManager.cpp,我们查看一下defaultServiceManager的实现过程:

获取BpServiceManager过程

sp<IServiceManager> defaultServiceManager()
	/*把handle(0)转化为IServiceManager接口(BpServiceManager),*/
	gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));
		/*获得一个代理对象,指定其Handle为0*/
		getStrongProxyForHandle(0);
			/*该处的handle为0,mhandle = handle*/
			b = new BpBinder(handle); 

下面我们分析

/*把handle(0)转化为IServiceManager接口(BpServiceManager),*/
gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));

在这里等价为:

interface_cast<IServiceManager>(new BpBinder(0)/*等价INTERFACE::asInterface(obj)*/
	IServiceManager::asInterface(obj);
		/*其中obj为new BpBinder(0)*/
		return BpServiceManager(obj)

下面我们看看BpServiceManager的构造函数,打开IServiceManager.cpp文件:

    BpServiceManager(const sp<IBinder>& impl): BpInterface<IServiceManager>(impl)

可以知道BpServiceManager继承于BpServiceManager,其BpInterface构造函数如下:

inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)
{
}

其上BpRefBase如下:

BpRefBase::BpRefBase(const sp<IBinder>& o): mRemote(o.get()), mRefs(NULL), mState(0)

通过上面的分析,我们做一些总结,defaultServiceManager构造了一个BpServiceManager对象,其中他的mRemoto = new BpBinder(0),则mRemoto.handle=0.

下面我能分析获取BpHelloService的过程,

获取BpHelloService的过程,

代开test_client.cpp

	/*getService在IServiceManager.cpp中实现*/
    sp<IBinder> binder =sm->getService(String16("hello"));
    	sp<IBinder> svc = checkService(name);
    		//构建数据,name=“hello”
    		data.writeString16(name);
    		/*发起数据传输*/
    		remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
    		/*接收数据时候,取出数据handle然后返回*/
    		return reply.readStrongBinder();
    			return unflatten_binder(ProcessState::self(), *this, val);
    				const flat_binder_object* flat = in.readObject(false);
    				/*取出handle*/
    				*out = proc->getStrongProxyForHandle(flat->handle)
    					b = new BpBinder(handle); 
	/* service肯定是BpHelloServie指针 */
	/*把binder转换为IHelloService接口(BphelloService对象)*/
	/*binder是一个Bpbinder对象,里面含有HelloService的handle*/
    sp<IHelloService> service =interface_cast<IHelloService>(binder);

现在我们总结一下获取BpHelloService的过程,调用BpServiceManage的getService的函数,获得一个flat_dinder_object,从中取出handlr,创建一个Bpbinder(handle).
然后通过interface_cast使用Bpbinder创建一个BpHelloService对象。

获取过程异同点

下面我们来看看获得BpHelloService与BpServiceManager的不同点,如下:
在这里插入图片描述
他们的重点在于handle,构建BpServiceManager其handle为0,BpHelloService的handle来自于getservice()。

BpServiceManager派生于BpRefBase,含有IBinder+mRemote指针。
BpHelloService也派生于BpRefBase,mRemote指向Bpbinder对象,其含有handle。

获得BpServiceManager获得BpHelloService,最终:

sp<IServiceManager> defaultServiceManager()
	/*把handle(0)转化为IServiceManager接口(BpServiceManager),*/
	gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));

现在我们看看另外一个问题:
代理类如何发送数据ioctl,数据中含有handle,以及其他构造参数。我们打开BpHelloService.app:

	void sayhello(void)
	{
		/* 构造/发送数据 */

        Parcel data, reply;
        data.writeInt32(0);

        remote()->transact(HELLO_SVR_CMD_SAYHELLO, data, &reply);
	}

首先构造数据,然后调用 remote()->transact发送。其中的remote是在Bpbinder.cpp实现:

status_t BpBinder::transact(
	status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);

猜你喜欢

转载自blog.csdn.net/weixin_43013761/article/details/89071265