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:
22using android::BAD_TYPE;
23using android::Looper;
24using android::LooperCallback;
25using android::OK;
26using android::sp;
27using android::status_t;
28
29// libhwbinder:
30using android::hardware::IPCThreadState;
31
32// libhidl
33using android::hardware::configureRpcThreadpool;
34using android::hardware::hidl_string;
35using android::hardware::hidl_vec;
36
37// hidl types
38using android::hidl::manager::V1_0::BnHwServiceManager;
39using android::hidl::manager::V1_0::IServiceManager;
40using android::hidl::token::V1_0::ITokenManager;
41
42// implementations
43using android::hidl::manager::V1_0::implementation::ServiceManager;
44using android::hidl::token::V1_0::implementation::TokenManager;
45
46static std::string serviceName = "default";
47
48class BinderCallback : public LooperCallback {
49public:
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
59int 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