blob: 847b06fd415c51c732e07ea21b3fab96780ffdb1 [file] [log] [blame]
#include <iostream>
#include <map>
#include <unistd.h>
#include <hwbinder/IInterface.h>
#include <hwbinder/IPCThreadState.h>
#include <hwbinder/IServiceManager.h>
#include <hwbinder/ProcessState.h>
#include <hwbinder/Status.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/Looper.h>
#include <utils/StrongPointer.h>
#include <android/hardware/tests/BnTestService.h>
// libutils:
using android::Looper;
using android::LooperCallback;
using android::OK;
using android::sp;
using android::String16;
// libhwbinder:
using android::hardware::BnInterface;
using android::hardware::defaultServiceManager;
using android::hardware::IInterface;
using android::hardware::IPCThreadState;
using android::hardware::Parcel;
using android::hardware::ProcessState;
using android::hardware::Status;
using android::hardware::hidl_version;
using android::hardware::make_hidl_version;
using android::hardware::from_ref;
// Standard library
using std::cerr;
using std::cout;
using std::endl;
using std::map;
using std::string;
using std::unique_ptr;
using std::vector;
// Generated HIDL files
using android::hardware::tests::BnTestService;
namespace {
class BinderCallback : public LooperCallback {
public:
BinderCallback() {}
~BinderCallback() override {}
int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
IPCThreadState::self()->handlePolledCommands();
return 1; // Continue receiving callbacks.
}
};
class TestService : public BnTestService {
public:
TestService() {}
virtual ~TestService() = default;
virtual Status echoInteger(int32_t echo_me, const ITestService::simple_t* my_struct, ITestService::echoInteger_cb callback) {
std::cout << "struct at addr " << (void *)my_struct << std::endl;
std::cout << "int1 " << my_struct->int1 << " int2 " << my_struct->int2 << std::endl;
std::cout << "uint8 at position 18 is " << static_cast<int>(my_struct->data.buffer[18]) << std::endl;
callback(echo_me);
printf("Value is %d\n", my_struct->data.buffer[18]);
return Status::ok();
}
virtual Status shareBufferWithRef(int buffer, ITestService::shareBufferWithRef_cb callback) {
// Map back to struct lots_of_data
ITestService::lots_of_data* dataPtr;
if (from_ref(buffer, &dataPtr)) {
// Failed
callback(1);
} else {
cout << "Data element at position 1481 is " << unsigned(dataPtr->buffer[1481]) << endl;
callback(0);
}
return Status::ok();
}
private:
};
int Run() {
android::sp<TestService> service = new TestService;
sp<Looper> looper(Looper::prepare(0 /* opts */));
int binder_fd = -1;
ProcessState::self()->setThreadPoolMaxThreadCount(0);
IPCThreadState::self()->disableBackgroundScheduling(true);
IPCThreadState::self()->setupPolling(&binder_fd);
ALOGI("Got binder FD %d", binder_fd);
if (binder_fd < 0) return -1;
sp<BinderCallback> cb(new BinderCallback);
if (looper->addFd(binder_fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb,
nullptr) != 1) {
ALOGE("Failed to add binder FD to Looper");
return -1;
}
hidl_version version = android::hardware::make_hidl_version(4,1);
defaultServiceManager()->addService(service->getInterfaceDescriptor(),
service, version);
ALOGI("Entering loop");
while (true) {
const int result = looper->pollAll(-1 /* timeoutMillis */);
ALOGI("Looper returned %d", result);
}
return 0;
}
} // namespace
int main(int /* argc */, char* /* argv */ []) {
return Run();
}