我们的演示程序分为客户端进程和服务端进程。
首先是服务端进程:首先通过 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;
}
需要先运行客户端,再运行服务端。