android11 input子系统入门之InputChannel跨进程使用Demo

我们的演示程序分为客户端进程和服务端进程。
首先是服务端进程:首先通过 InputChannel::openInputChannelPair函数生成serverChannel, clientChannel,然后把clientChannel通过binder驱动发送给客户端进程。
然后我们调用 serverChannel->sendMessage(&serverMsg)发送按键信息给此 serverChannel对应的clientChannel。

#include <utils/Trace.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <iostream>
#include <stdint.h>
#include <sys/types.h>
#include <set>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <inttypes.h>
#include <input/InputTransport.h>

#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
#include <android-base/properties.h>
#include <errno.h>
#include <fcntl.h>
#include <fstream>
#include <poll.h>

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <sys/wait.h>

#include <private/binder/binder_module.h>
#include <sys/epoll.h>
#include <sys/prctl.h>

using namespace android;
using namespace std;

enum BinderLibTestTranscationCode
{
	AAAA = IBinder::FIRST_CALL_TRANSACTION,
};

static String16 binderLibTestServiceName = String16("test.binderLib.input02");

int main(int argc, char **argv)
{
	sp<IBinder> m_server;
	ProcessState::self()->startThreadPool();
	status_t ret;
	sp<IServiceManager> sm = defaultServiceManager();
	m_server = sm->getService(binderLibTestServiceName);
	sp<InputChannel> serverChannel, clientChannel;
	status_t result = InputChannel::openInputChannelPair("channel name",
														 serverChannel, clientChannel);
	cout << serverChannel->getName() << endl;
	cout << clientChannel->getName() << endl;
	Parcel data, reply;
	clientChannel->write(data);
	ret = m_server->transact(AAAA, data, &reply);
	std::cout << ret << std::endl;

	for (int i = 0; i < 10; i++)
	{
		InputMessage serverMsg;
		memset(&serverMsg, 0, sizeof(InputMessage));
		serverMsg.header.type = InputMessage::Type::KEY;
		serverMsg.body.key.action = AKEY_EVENT_ACTION_DOWN;
		serverMsg.body.key.keyCode = 123 + i;
		printf("serverChannel sendMessage\n");
		serverChannel->sendMessage(&serverMsg);
	}
	printf("end\n");
	IPCThreadState::self()->joinThreadPool();
	return 0;
}

下面是客户端的程序:
1 注册服务到sm。
2 接受服务端发过来的 clientChannel。
3 读取clientChannel的信息。

#include <utils/Trace.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <iostream>
#include <stdint.h>
#include <sys/types.h>
#include <set>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <inttypes.h>
#include <input/InputTransport.h>
#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
#include <android-base/properties.h>
#include <errno.h>
#include <fcntl.h>
#include <fstream>
#include <poll.h>

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <sys/wait.h>

#include <private/binder/binder_module.h>
#include <sys/epoll.h>
#include <sys/prctl.h>

using namespace android;
using namespace std;

sp<InputChannel> clientChannel;

void receiveMessage()
{
	while (1)
	{
		if (clientChannel == nullptr)
		{
			printf("clientChannel is null\n");
			sleep(4);
			continue;
		}
		InputMessage clientMsg;
		status_t s = clientChannel->receiveMessage(&clientMsg);
		printf("clientChannel receiveMessage\n");
		if (s == OK)
		{
			printf("OK\n");
			cout << clientMsg.body.key.action << endl;
			cout << clientMsg.body.key.keyCode << endl;
			continue;
		}
		else if (s == WOULD_BLOCK)
		{
			printf("WOULD_BLOCK \n");
		}
		else if (s == DEAD_OBJECT)
		{
			printf("DEAD_OBJECT  \n");
		}
		else
		{
			printf("status_t:  %d  \n", s);
		}
		sleep(4);
	}
}

enum BinderLibTestTranscationCode
{
	AAAA = IBinder::FIRST_CALL_TRANSACTION,
};

static String16 binderLibTestServiceName = String16("test.binderLib.input02");

class BinderLibTestService : public BBinder
{
public:
	explicit BinderLibTestService()
	{
	}
	~BinderLibTestService()
	{
	}

	virtual status_t onTransact(uint32_t code, const Parcel &data,
								Parcel *reply, uint32_t flags = 0) override
	{
		switch (code)
		{
		case AAAA:
		{
			clientChannel = InputChannel::read(data);
			return NO_ERROR;
		}
		default:
			return UNKNOWN_TRANSACTION;
		};
	}

private:
};

int main(int argc, char **argv)
{
	sp<IBinder> m_server;
	ProcessState::self()->startThreadPool();
	status_t ret;
	sp<IServiceManager> sm = defaultServiceManager();
	sp<BinderLibTestService> testService = new BinderLibTestService();
	ret = sm->addService(binderLibTestServiceName, testService);
	thread first(receiveMessage);
	IPCThreadState::self()->joinThreadPool();
	return 0;
}

需要先运行客户端,再运行服务端。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值