Loading libs/binder/ndk/include_platform/android/binder_process.h +28 −0 Original line number Diff line number Diff line Loading @@ -19,10 +19,15 @@ #include <stdint.h> #include <sys/cdefs.h> #include <android/binder_status.h> __BEGIN_DECLS /** * This creates a threadpool for incoming binder transactions if it has not already been created. * * When using this, it is expected that ABinderProcess_setupPolling and * ABinderProcess_handlePolledCommands are not used. */ void ABinderProcess_startThreadPool(); /** Loading @@ -37,4 +42,27 @@ bool ABinderProcess_setThreadPoolMaxThreadCount(uint32_t numThreads); */ void ABinderProcess_joinThreadPool(); /** * This gives you an fd to wait on. Whenever data is available on the fd, * ABinderProcess_handlePolledCommands can be called to handle binder queries. * This is expected to be used in a single threaded process which waits on * events from multiple different fds. * * When using this, it is expected ABinderProcess_startThreadPool and * ABinderProcess_joinThreadPool are not used. * * \param fd out param corresponding to the binder domain opened in this * process. * \return STATUS_OK on success */ __attribute__((weak)) binder_status_t ABinderProcess_setupPolling(int* fd) __INTRODUCED_IN(31); /** * This will handle all queued binder commands in this process and then return. * It is expected to be called whenever there is data on the fd. * * \return STATUS_OK on success */ __attribute__((weak)) binder_status_t ABinderProcess_handlePolledCommands() __INTRODUCED_IN(31); __END_DECLS libs/binder/ndk/libbinder_ndk.map.txt +2 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,8 @@ LIBBINDER_NDK30 { # introduced=30 LIBBINDER_NDK31 { # introduced=31 global: ABinderProcess_handlePolledCommands; # apex ABinderProcess_setupPolling; # apex AIBinder_getCallingSid; # apex AIBinder_setRequestingSid; # apex }; Loading libs/binder/ndk/process.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -34,3 +34,11 @@ bool ABinderProcess_setThreadPoolMaxThreadCount(uint32_t numThreads) { void ABinderProcess_joinThreadPool() { IPCThreadState::self()->joinThreadPool(); } binder_status_t ABinderProcess_setupPolling(int* fd) { return IPCThreadState::self()->setupPolling(fd); } binder_status_t ABinderProcess_handlePolledCommands() { return IPCThreadState::self()->handlePolledCommands(); } libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +28 −7 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <android/binder_process.h> #include <gtest/gtest.h> #include <iface/iface.h> #include <utils/Looper.h> // warning: this is assuming that libbinder_ndk is using the same copy // of libbinder that we are. Loading Loading @@ -107,19 +108,39 @@ class MyFoo : public IFoo { } }; int manualService(const char* instance) { ABinderProcess_setThreadPoolMaxThreadCount(0); void manualService(const char* instance) { // Strong reference to MyFoo kept by service manager. binder_status_t status = (new MyFoo)->addService(instance); if (status != STATUS_OK) { LOG(FATAL) << "Could not register: " << status << " " << instance; } } int manualPollingService(const char* instance) { int fd; CHECK(STATUS_OK == ABinderProcess_setupPolling(&fd)); manualService(instance); ABinderProcess_joinThreadPool(); class Handler : public LooperCallback { int handleEvent(int /*fd*/, int /*events*/, void* /*data*/) override { ABinderProcess_handlePolledCommands(); return 1; // Continue receiving callbacks. } }; return 1; // should not return sp<Looper> looper = Looper::prepare(0 /* opts */); looper->addFd(fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, new Handler(), nullptr /*data*/); // normally, would add additional fds while (true) { looper->pollAll(-1 /* timeoutMillis */); } return 1; // should not reach } int manualThreadPoolService(const char* instance) { ABinderProcess_setThreadPoolMaxThreadCount(0); manualService(instance); ABinderProcess_joinThreadPool(); return 1; } // This is too slow Loading Loading @@ -448,11 +469,11 @@ int main(int argc, char* argv[]) { if (fork() == 0) { prctl(PR_SET_PDEATHSIG, SIGHUP); return manualService(IFoo::kInstanceNameToDieFor); return manualThreadPoolService(IFoo::kInstanceNameToDieFor); } if (fork() == 0) { prctl(PR_SET_PDEATHSIG, SIGHUP); return manualService(IFoo::kSomeInstanceName); return manualPollingService(IFoo::kSomeInstanceName); } if (fork() == 0) { prctl(PR_SET_PDEATHSIG, SIGHUP); Loading Loading
libs/binder/ndk/include_platform/android/binder_process.h +28 −0 Original line number Diff line number Diff line Loading @@ -19,10 +19,15 @@ #include <stdint.h> #include <sys/cdefs.h> #include <android/binder_status.h> __BEGIN_DECLS /** * This creates a threadpool for incoming binder transactions if it has not already been created. * * When using this, it is expected that ABinderProcess_setupPolling and * ABinderProcess_handlePolledCommands are not used. */ void ABinderProcess_startThreadPool(); /** Loading @@ -37,4 +42,27 @@ bool ABinderProcess_setThreadPoolMaxThreadCount(uint32_t numThreads); */ void ABinderProcess_joinThreadPool(); /** * This gives you an fd to wait on. Whenever data is available on the fd, * ABinderProcess_handlePolledCommands can be called to handle binder queries. * This is expected to be used in a single threaded process which waits on * events from multiple different fds. * * When using this, it is expected ABinderProcess_startThreadPool and * ABinderProcess_joinThreadPool are not used. * * \param fd out param corresponding to the binder domain opened in this * process. * \return STATUS_OK on success */ __attribute__((weak)) binder_status_t ABinderProcess_setupPolling(int* fd) __INTRODUCED_IN(31); /** * This will handle all queued binder commands in this process and then return. * It is expected to be called whenever there is data on the fd. * * \return STATUS_OK on success */ __attribute__((weak)) binder_status_t ABinderProcess_handlePolledCommands() __INTRODUCED_IN(31); __END_DECLS
libs/binder/ndk/libbinder_ndk.map.txt +2 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,8 @@ LIBBINDER_NDK30 { # introduced=30 LIBBINDER_NDK31 { # introduced=31 global: ABinderProcess_handlePolledCommands; # apex ABinderProcess_setupPolling; # apex AIBinder_getCallingSid; # apex AIBinder_setRequestingSid; # apex }; Loading
libs/binder/ndk/process.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -34,3 +34,11 @@ bool ABinderProcess_setThreadPoolMaxThreadCount(uint32_t numThreads) { void ABinderProcess_joinThreadPool() { IPCThreadState::self()->joinThreadPool(); } binder_status_t ABinderProcess_setupPolling(int* fd) { return IPCThreadState::self()->setupPolling(fd); } binder_status_t ABinderProcess_handlePolledCommands() { return IPCThreadState::self()->handlePolledCommands(); }
libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +28 −7 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <android/binder_process.h> #include <gtest/gtest.h> #include <iface/iface.h> #include <utils/Looper.h> // warning: this is assuming that libbinder_ndk is using the same copy // of libbinder that we are. Loading Loading @@ -107,19 +108,39 @@ class MyFoo : public IFoo { } }; int manualService(const char* instance) { ABinderProcess_setThreadPoolMaxThreadCount(0); void manualService(const char* instance) { // Strong reference to MyFoo kept by service manager. binder_status_t status = (new MyFoo)->addService(instance); if (status != STATUS_OK) { LOG(FATAL) << "Could not register: " << status << " " << instance; } } int manualPollingService(const char* instance) { int fd; CHECK(STATUS_OK == ABinderProcess_setupPolling(&fd)); manualService(instance); ABinderProcess_joinThreadPool(); class Handler : public LooperCallback { int handleEvent(int /*fd*/, int /*events*/, void* /*data*/) override { ABinderProcess_handlePolledCommands(); return 1; // Continue receiving callbacks. } }; return 1; // should not return sp<Looper> looper = Looper::prepare(0 /* opts */); looper->addFd(fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, new Handler(), nullptr /*data*/); // normally, would add additional fds while (true) { looper->pollAll(-1 /* timeoutMillis */); } return 1; // should not reach } int manualThreadPoolService(const char* instance) { ABinderProcess_setThreadPoolMaxThreadCount(0); manualService(instance); ABinderProcess_joinThreadPool(); return 1; } // This is too slow Loading Loading @@ -448,11 +469,11 @@ int main(int argc, char* argv[]) { if (fork() == 0) { prctl(PR_SET_PDEATHSIG, SIGHUP); return manualService(IFoo::kInstanceNameToDieFor); return manualThreadPoolService(IFoo::kInstanceNameToDieFor); } if (fork() == 0) { prctl(PR_SET_PDEATHSIG, SIGHUP); return manualService(IFoo::kSomeInstanceName); return manualPollingService(IFoo::kSomeInstanceName); } if (fork() == 0) { prctl(PR_SET_PDEATHSIG, SIGHUP); Loading