123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- /*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #define LOG_TAG "hwservicemanager"
- #include <utils/Log.h>
- #include <inttypes.h>
- #include <unistd.h>
- #include <sys/timerfd.h>
- #include <android/hidl/token/1.0/ITokenManager.h>
- #include <cutils/properties.h>
- #include <hidl/HidlBinderSupport.h>
- #include <hidl/HidlTransportSupport.h>
- #include <hidl/Status.h>
- #include <hwbinder/IPCThreadState.h>
- #include <hwbinder/ProcessState.h>
- #include <utils/Errors.h>
- #include <utils/Looper.h>
- #include <utils/StrongPointer.h>
- #include "ServiceManager.h"
- #include "TokenManager.h"
- // libutils:
- using android::sp;
- using android::Looper;
- using android::LooperCallback;
- // libhwbinder:
- using android::hardware::BHwBinder;
- using android::hardware::IBinder;
- using android::hardware::IPCThreadState;
- using android::hardware::ProcessState;
- // libhidl
- using android::hardware::handleTransportPoll;
- using android::hardware::setRequestingSid;
- using android::hardware::HidlReturnRestriction;
- using android::hardware::setProcessHidlReturnRestriction;
- using android::hardware::setupTransportPolling;
- using android::hardware::toBinder;
- // implementations
- using android::hidl::manager::implementation::ServiceManager;
- using android::hidl::manager::V1_0::IServiceManager;
- using android::hidl::token::V1_0::implementation::TokenManager;
- static std::string serviceName = "default";
- class HwBinderCallback : public LooperCallback {
- public:
- static sp<HwBinderCallback> setupTo(const sp<Looper>& looper) {
- sp<HwBinderCallback> cb = new HwBinderCallback;
- int fdHwBinder = setupTransportPolling();
- LOG_ALWAYS_FATAL_IF(fdHwBinder < 0, "Failed to setupTransportPolling: %d", fdHwBinder);
- // Flush after setupPolling(), to make sure the binder driver
- // knows about this thread handling commands.
- IPCThreadState::self()->flushCommands();
- int ret = looper->addFd(fdHwBinder,
- Looper::POLL_CALLBACK,
- Looper::EVENT_INPUT,
- cb,
- nullptr /*data*/);
- LOG_ALWAYS_FATAL_IF(ret != 1, "Failed to add binder FD to Looper");
- return cb;
- }
- int handleEvent(int fd, int /*events*/, void* /*data*/) override {
- handleTransportPoll(fd);
- return 1; // Continue receiving callbacks.
- }
- };
- // LooperCallback for IClientCallback
- class ClientCallbackCallback : public LooperCallback {
- public:
- static sp<ClientCallbackCallback> setupTo(const sp<Looper>& looper, const sp<ServiceManager>& manager) {
- sp<ClientCallbackCallback> cb = new ClientCallbackCallback(manager);
- int fdTimer = timerfd_create(CLOCK_MONOTONIC, 0 /*flags*/);
- LOG_ALWAYS_FATAL_IF(fdTimer < 0, "Failed to timerfd_create: fd: %d err: %d", fdTimer, errno);
- itimerspec timespec {
- .it_interval = {
- .tv_sec = 5,
- .tv_nsec = 0,
- },
- .it_value = {
- .tv_sec = 5,
- .tv_nsec = 0,
- },
- };
- int timeRes = timerfd_settime(fdTimer, 0 /*flags*/, ×pec, nullptr);
- LOG_ALWAYS_FATAL_IF(timeRes < 0, "Failed to timerfd_settime: res: %d err: %d", timeRes, errno);
- int addRes = looper->addFd(fdTimer,
- Looper::POLL_CALLBACK,
- Looper::EVENT_INPUT,
- cb,
- nullptr);
- LOG_ALWAYS_FATAL_IF(addRes != 1, "Failed to add client callback FD to Looper");
- return cb;
- }
- int handleEvent(int fd, int /*events*/, void* /*data*/) override {
- uint64_t expirations;
- int ret = read(fd, &expirations, sizeof(expirations));
- if (ret != sizeof(expirations)) {
- ALOGE("Read failed to callback FD: ret: %d err: %d", ret, errno);
- }
- mManager->handleClientCallbacks();
- return 1; // Continue receiving callbacks.
- }
- private:
- ClientCallbackCallback(const sp<ServiceManager>& manager) : mManager(manager) {}
- sp<ServiceManager> mManager;
- };
- int main() {
- // If hwservicemanager crashes, the system may be unstable and hard to debug. This is both why
- // we log this and why we care about this at all.
- setProcessHidlReturnRestriction(HidlReturnRestriction::ERROR_IF_UNCHECKED);
- sp<ServiceManager> manager = new ServiceManager();
- setRequestingSid(manager, true);
- if (!manager->add(serviceName, manager).withDefault(false)) {
- ALOGE("Failed to register hwservicemanager with itself.");
- }
- sp<TokenManager> tokenManager = new TokenManager();
- if (!manager->add(serviceName, tokenManager).withDefault(false)) {
- ALOGE("Failed to register ITokenManager with hwservicemanager.");
- }
- // Tell IPCThreadState we're the service manager
- sp<IBinder> binder = toBinder<IServiceManager>(manager);
- sp<BHwBinder> service = static_cast<BHwBinder*>(binder.get()); // local binder object
- IPCThreadState::self()->setTheContextObject(service);
- // Then tell the kernel
- ProcessState::self()->becomeContextManager(nullptr, nullptr);
- int rc = property_set("hwservicemanager.ready", "true");
- if (rc) {
- ALOGE("Failed to set \"hwservicemanager.ready\" (error %d). "\
- "HAL services will not start!\n", rc);
- }
- sp<Looper> looper = Looper::prepare(0 /* opts */);
- (void)HwBinderCallback::setupTo(looper);
- (void)ClientCallbackCallback::setupTo(looper, manager);
- ALOGI("hwservicemanager is ready now.");
- while (true) {
- looper->pollAll(-1 /* timeoutMillis */);
- }
- return 0;
- }
|