服务端
#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 <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 <pthread.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 {
BINDER_LIB_TEST_NOP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
BINDER_LIB_TEST_REGISTER_SERVER,
BINDER_LIB_TEST_ADD_SERVER,
BINDER_LIB_TEST_ADD_POLL_SERVER,
BINDER_LIB_TEST_CALL_BACK,
BINDER_LIB_TEST_CALL_BACK_VERIFY_BUF,
BINDER_LIB_TEST_DELAYED_CALL_BACK,
BINDER_LIB_TEST_NOP_CALL_BACK,
BINDER_LIB_TEST_GET_SELF_TRANSACTION,
BINDER_LIB_TEST_GET_ID_TRANSACTION,
BINDER_LIB_TEST_INDIRECT_TRANSACTION,
BINDER_LIB_TEST_SET_ERROR_TRANSACTION,
BINDER_LIB_TEST_GET_STATUS_TRANSACTION,
BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION,
BINDER_LIB_TEST_LINK_DEATH_TRANSACTION,
BINDER_LIB_TEST_WRITE_FILE_TRANSACTION,
BINDER_LIB_TEST_WRITE_PARCEL_FILE_DESCRIPTOR_TRANSACTION,
BINDER_LIB_TEST_EXIT_TRANSACTION,
BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION,
BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION,
BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION,
BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION,
BINDER_LIB_TEST_GET_SCHEDULING_POLICY,
BINDER_LIB_TEST_NOP_TRANSACTION_WAIT,
BINDER_LIB_TEST_GETPID,
BINDER_LIB_TEST_ECHO_VECTOR,
BINDER_LIB_TEST_REJECT_BUF,
};
static String16 binderLibTestServiceName = String16("test.binderLib.0921");
class BinderLibTestService: public BBinder {
public:
explicit BinderLibTestService(int32_t id)
{
}
~BinderLibTestService() {
exit(EXIT_SUCCESS);
}
virtual status_t onTransact(uint32_t code, const Parcel &data,
Parcel *reply, uint32_t flags = 0) override {
printf("%s: code %d\n", __func__, code);
switch (code) {
case BINDER_LIB_TEST_WRITE_FILE_TRANSACTION: {
int ret;
int fd;
fd = data.readFileDescriptor();
if (fd < 0) {
printf("BAD_VALUE\n");
return BAD_VALUE;
}
char a[] = "hello,andy\n";
ret = write(fd, a, strlen(a));
printf("write: %d\n",ret);
close(fd);
printf("NO_ERROR\n");
return NO_ERROR;
}
case BINDER_LIB_TEST_NOP_CALL_BACK: {
Parcel data2, reply2;
sp<IBinder> binder;
binder = data.readStrongBinder();
if (binder == nullptr) {
return BAD_VALUE;
}
data2.writeInt32(8888);
binder->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
return NO_ERROR;
}
default:
return UNKNOWN_TRANSACTION;
};
}
private:
};
int main(int argc, char **argv) {
sp<IBinder> m_server;
ProcessState::self()->startThreadPool();
printf("10\n");
status_t ret;
sp<IServiceManager> sm = defaultServiceManager();
BinderLibTestService *testServicePtr;
int index = 0;
sp<BinderLibTestService> testService = new BinderLibTestService(index);
printf("addService\n");
ret = sm->addService(binderLibTestServiceName, testService);
printf("end\n");
IPCThreadState::self()->joinThreadPool();
return 0;
}
客户端,调用 writeFileDescriptor
#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 <unistd.h>
#include <stdio.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 <pthread.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 {
BINDER_LIB_TEST_NOP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
BINDER_LIB_TEST_REGISTER_SERVER,
BINDER_LIB_TEST_ADD_SERVER,
BINDER_LIB_TEST_ADD_POLL_SERVER,
BINDER_LIB_TEST_CALL_BACK,
BINDER_LIB_TEST_CALL_BACK_VERIFY_BUF,
BINDER_LIB_TEST_DELAYED_CALL_BACK,
BINDER_LIB_TEST_NOP_CALL_BACK,
BINDER_LIB_TEST_GET_SELF_TRANSACTION,
BINDER_LIB_TEST_GET_ID_TRANSACTION,
BINDER_LIB_TEST_INDIRECT_TRANSACTION,
BINDER_LIB_TEST_SET_ERROR_TRANSACTION,
BINDER_LIB_TEST_GET_STATUS_TRANSACTION,
BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION,
BINDER_LIB_TEST_LINK_DEATH_TRANSACTION,
BINDER_LIB_TEST_WRITE_FILE_TRANSACTION,
BINDER_LIB_TEST_WRITE_PARCEL_FILE_DESCRIPTOR_TRANSACTION,
BINDER_LIB_TEST_EXIT_TRANSACTION,
BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION,
BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION,
BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION,
BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION,
BINDER_LIB_TEST_GET_SCHEDULING_POLICY,
BINDER_LIB_TEST_NOP_TRANSACTION_WAIT,
BINDER_LIB_TEST_GETPID,
BINDER_LIB_TEST_ECHO_VECTOR,
BINDER_LIB_TEST_REJECT_BUF,
};
static String16 binderLibTestServiceName = String16("test.binderLib.0921");
class BinderLibTestCallBack: public BBinder {
public:
BinderLibTestCallBack() :
m_result(0) {
}
status_t getResult(void) {
return m_result;
}
private:
virtual status_t onTransact(uint32_t code, const Parcel &data,
Parcel *reply, uint32_t flags = 0) {
(void) reply;
(void) flags;
switch (code) {
case BINDER_LIB_TEST_CALL_BACK: {
status_t status = data.readInt32();
if (status != NO_ERROR) {
m_result = status;
}
printf("cb: callback called\n");
std::cout << "cb: " << m_result << std::endl;
// triggerEvent();
return NO_ERROR;
}
default:
return UNKNOWN_TRANSACTION;
}
}
status_t m_result;
const uint8_t *m_prev_end;
};
class TestDeathRecipient: public IBinder::DeathRecipient {
private:
virtual void binderDied(const wp<IBinder> &who) {
printf("binderDied\n");
}
;
};
void f() {
int fd = open("/system/bin/files0", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);
if (fd < 0) {
perror(NULL);
return;
}
char a[] = "abcdef0123456\n";
write(fd, a, strlen(a));
close(fd);
}
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<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
ret = m_server->linkToDeath(testDeathRecipient);
Parcel data, reply;
int fd = open("/system/bin/files0", O_RDWR | O_CREAT | O_APPEND, S_IRWXU);
if (fd < 0) {
perror(NULL);
return -1;
}
data.writeFileDescriptor(fd, true);
ret = m_server->transact(BINDER_LIB_TEST_WRITE_FILE_TRANSACTION, data,
&reply);
std::cout << ret << std::endl;
printf("end\n");
IPCThreadState::self()->joinThreadPool();
return 0;
}