Home | History | Annotate | Download | only in hwservicemanager
      1 #define LOG_TAG "hwservicemanager"
      2 
      3 #include <utils/Log.h>
      4 
      5 #include <inttypes.h>
      6 #include <unistd.h>
      7 
      8 #include <android/hidl/manager/1.0/BnHwServiceManager.h>
      9 #include <android/hidl/manager/1.0/IServiceManager.h>
     10 #include <android/hidl/token/1.0/ITokenManager.h>
     11 #include <cutils/properties.h>
     12 #include <hidl/Status.h>
     13 #include <hwbinder/IPCThreadState.h>
     14 #include <utils/Errors.h>
     15 #include <utils/Looper.h>
     16 #include <utils/StrongPointer.h>
     17 
     18 #include "ServiceManager.h"
     19 #include "TokenManager.h"
     20 
     21 // libutils:
     22 using android::BAD_TYPE;
     23 using android::Looper;
     24 using android::LooperCallback;
     25 using android::OK;
     26 using android::sp;
     27 using android::status_t;
     28 
     29 // libhwbinder:
     30 using android::hardware::IPCThreadState;
     31 
     32 // libhidl
     33 using android::hardware::configureRpcThreadpool;
     34 using android::hardware::hidl_string;
     35 using android::hardware::hidl_vec;
     36 
     37 // hidl types
     38 using android::hidl::manager::V1_0::BnHwServiceManager;
     39 using android::hidl::manager::V1_0::IServiceManager;
     40 using android::hidl::token::V1_0::ITokenManager;
     41 
     42 // implementations
     43 using android::hidl::manager::V1_0::implementation::ServiceManager;
     44 using android::hidl::token::V1_0::implementation::TokenManager;
     45 
     46 static std::string serviceName = "default";
     47 
     48 class BinderCallback : public LooperCallback {
     49 public:
     50     BinderCallback() {}
     51     ~BinderCallback() override {}
     52 
     53     int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
     54         IPCThreadState::self()->handlePolledCommands();
     55         return 1;  // Continue receiving callbacks.
     56     }
     57 };
     58 
     59 int main() {
     60     configureRpcThreadpool(1, true /* callerWillJoin */);
     61 
     62     ServiceManager *manager = new ServiceManager();
     63 
     64     if (!manager->add(serviceName, manager)) {
     65         ALOGE("Failed to register hwservicemanager with itself.");
     66     }
     67 
     68     TokenManager *tokenManager = new TokenManager();
     69 
     70     if (!manager->add(serviceName, tokenManager)) {
     71         ALOGE("Failed to register ITokenManager with hwservicemanager.");
     72     }
     73 
     74     sp<Looper> looper(Looper::prepare(0 /* opts */));
     75 
     76     int binder_fd = -1;
     77 
     78     IPCThreadState::self()->setupPolling(&binder_fd);
     79     if (binder_fd < 0) {
     80         ALOGE("Failed to aquire binder FD. Aborting...");
     81         return -1;
     82     }
     83     // Flush after setupPolling(), to make sure the binder driver
     84     // knows about this thread handling commands.
     85     IPCThreadState::self()->flushCommands();
     86 
     87     sp<BinderCallback> cb(new BinderCallback);
     88     if (looper->addFd(binder_fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb,
     89             nullptr) != 1) {
     90         ALOGE("Failed to add hwbinder FD to Looper. Aborting...");
     91         return -1;
     92     }
     93 
     94     // Tell IPCThreadState we're the service manager
     95     sp<BnHwServiceManager> service = new BnHwServiceManager(manager);
     96     IPCThreadState::self()->setTheContextObject(service);
     97     // Then tell binder kernel
     98     ioctl(binder_fd, BINDER_SET_CONTEXT_MGR, 0);
     99     // Only enable FIFO inheritance for hwbinder
    100     // FIXME: remove define when in the kernel
    101 #define BINDER_SET_INHERIT_FIFO_PRIO    _IO('b', 10)
    102 
    103     int rc = ioctl(binder_fd, BINDER_SET_INHERIT_FIFO_PRIO);
    104     if (rc) {
    105         ALOGE("BINDER_SET_INHERIT_FIFO_PRIO failed with error %d\n", rc);
    106     }
    107 
    108     rc = property_set("hwservicemanager.ready", "true");
    109     if (rc) {
    110         ALOGE("Failed to set \"hwservicemanager.ready\" (error %d). "\
    111               "HAL services will not start!\n", rc);
    112     }
    113 
    114     while (true) {
    115         looper->pollAll(-1 /* timeoutMillis */);
    116     }
    117 
    118     return 0;
    119 }
    120