Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2019 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #include <android-base/logging.h> |
| 18 | #include <binder/IPCThreadState.h> |
| 19 | #include <binder/ProcessState.h> |
| 20 | #include <binder/Status.h> |
Jon Spivack | 9f503a4 | 2019-10-22 16:49:19 -0700 | [diff] [blame] | 21 | #include <sys/timerfd.h> |
| 22 | #include <utils/Looper.h> |
Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 23 | #include <utils/StrongPointer.h> |
| 24 | |
| 25 | #include "Access.h" |
| 26 | #include "ServiceManager.h" |
| 27 | |
Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 28 | using ::android::Access; |
Jon Spivack | 9f503a4 | 2019-10-22 16:49:19 -0700 | [diff] [blame] | 29 | using ::android::sp; |
| 30 | using ::android::Looper; |
| 31 | using ::android::LooperCallback; |
| 32 | using ::android::ProcessState; |
Steven Moreland | 46f380b | 2019-10-16 16:28:21 -0700 | [diff] [blame] | 33 | using ::android::IPCThreadState; |
| 34 | using ::android::ProcessState; |
| 35 | using ::android::ServiceManager; |
| 36 | using ::android::os::IServiceManager; |
| 37 | using ::android::sp; |
Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 38 | |
Jon Spivack | 9f503a4 | 2019-10-22 16:49:19 -0700 | [diff] [blame] | 39 | class BinderCallback : public LooperCallback { |
| 40 | public: |
| 41 | static sp<BinderCallback> setupTo(const sp<Looper>& looper) { |
Steven Moreland | b098318 | 2021-04-02 03:14:04 +0000 | [diff] [blame^] | 42 | sp<BinderCallback> cb = sp<BinderCallback>::make(); |
Jon Spivack | 9f503a4 | 2019-10-22 16:49:19 -0700 | [diff] [blame] | 43 | |
| 44 | int binder_fd = -1; |
| 45 | IPCThreadState::self()->setupPolling(&binder_fd); |
| 46 | LOG_ALWAYS_FATAL_IF(binder_fd < 0, "Failed to setupPolling: %d", binder_fd); |
| 47 | |
Jon Spivack | 9f503a4 | 2019-10-22 16:49:19 -0700 | [diff] [blame] | 48 | int ret = looper->addFd(binder_fd, |
| 49 | Looper::POLL_CALLBACK, |
| 50 | Looper::EVENT_INPUT, |
| 51 | cb, |
| 52 | nullptr /*data*/); |
| 53 | LOG_ALWAYS_FATAL_IF(ret != 1, "Failed to add binder FD to Looper"); |
| 54 | |
| 55 | return cb; |
| 56 | } |
| 57 | |
| 58 | int handleEvent(int /* fd */, int /* events */, void* /* data */) override { |
| 59 | IPCThreadState::self()->handlePolledCommands(); |
| 60 | return 1; // Continue receiving callbacks. |
| 61 | } |
| 62 | }; |
| 63 | |
| 64 | // LooperCallback for IClientCallback |
| 65 | class ClientCallbackCallback : public LooperCallback { |
| 66 | public: |
| 67 | static sp<ClientCallbackCallback> setupTo(const sp<Looper>& looper, const sp<ServiceManager>& manager) { |
Steven Moreland | b098318 | 2021-04-02 03:14:04 +0000 | [diff] [blame^] | 68 | sp<ClientCallbackCallback> cb = sp<ClientCallbackCallback>::make(manager); |
Jon Spivack | 9f503a4 | 2019-10-22 16:49:19 -0700 | [diff] [blame] | 69 | |
| 70 | int fdTimer = timerfd_create(CLOCK_MONOTONIC, 0 /*flags*/); |
| 71 | LOG_ALWAYS_FATAL_IF(fdTimer < 0, "Failed to timerfd_create: fd: %d err: %d", fdTimer, errno); |
| 72 | |
| 73 | itimerspec timespec { |
| 74 | .it_interval = { |
| 75 | .tv_sec = 5, |
| 76 | .tv_nsec = 0, |
| 77 | }, |
| 78 | .it_value = { |
| 79 | .tv_sec = 5, |
| 80 | .tv_nsec = 0, |
| 81 | }, |
| 82 | }; |
| 83 | |
| 84 | int timeRes = timerfd_settime(fdTimer, 0 /*flags*/, ×pec, nullptr); |
| 85 | LOG_ALWAYS_FATAL_IF(timeRes < 0, "Failed to timerfd_settime: res: %d err: %d", timeRes, errno); |
| 86 | |
| 87 | int addRes = looper->addFd(fdTimer, |
| 88 | Looper::POLL_CALLBACK, |
| 89 | Looper::EVENT_INPUT, |
| 90 | cb, |
| 91 | nullptr); |
| 92 | LOG_ALWAYS_FATAL_IF(addRes != 1, "Failed to add client callback FD to Looper"); |
| 93 | |
| 94 | return cb; |
| 95 | } |
| 96 | |
| 97 | int handleEvent(int fd, int /*events*/, void* /*data*/) override { |
| 98 | uint64_t expirations; |
| 99 | int ret = read(fd, &expirations, sizeof(expirations)); |
| 100 | if (ret != sizeof(expirations)) { |
| 101 | ALOGE("Read failed to callback FD: ret: %d err: %d", ret, errno); |
| 102 | } |
| 103 | |
| 104 | mManager->handleClientCallbacks(); |
| 105 | return 1; // Continue receiving callbacks. |
| 106 | } |
| 107 | private: |
Steven Moreland | b098318 | 2021-04-02 03:14:04 +0000 | [diff] [blame^] | 108 | friend sp<ClientCallbackCallback>; |
Jon Spivack | 9f503a4 | 2019-10-22 16:49:19 -0700 | [diff] [blame] | 109 | ClientCallbackCallback(const sp<ServiceManager>& manager) : mManager(manager) {} |
| 110 | sp<ServiceManager> mManager; |
| 111 | }; |
| 112 | |
Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 113 | int main(int argc, char** argv) { |
| 114 | if (argc > 2) { |
| 115 | LOG(FATAL) << "usage: " << argv[0] << " [binder driver]"; |
| 116 | } |
| 117 | |
| 118 | const char* driver = argc == 2 ? argv[1] : "/dev/binder"; |
| 119 | |
Steven Moreland | 1ac84c4 | 2019-07-10 17:51:27 -0700 | [diff] [blame] | 120 | sp<ProcessState> ps = ProcessState::initWithDriver(driver); |
| 121 | ps->setThreadPoolMaxThreadCount(0); |
| 122 | ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY); |
Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 123 | |
Steven Moreland | b098318 | 2021-04-02 03:14:04 +0000 | [diff] [blame^] | 124 | sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>()); |
Steven Moreland | 46f380b | 2019-10-16 16:28:21 -0700 | [diff] [blame] | 125 | if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) { |
| 126 | LOG(ERROR) << "Could not self register servicemanager"; |
| 127 | } |
| 128 | |
Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 129 | IPCThreadState::self()->setTheContextObject(manager); |
Steven Moreland | 6109662 | 2020-08-31 23:36:39 +0000 | [diff] [blame] | 130 | ps->becomeContextManager(); |
Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 131 | |
Jon Spivack | 9f503a4 | 2019-10-22 16:49:19 -0700 | [diff] [blame] | 132 | sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/); |
| 133 | |
| 134 | BinderCallback::setupTo(looper); |
| 135 | ClientCallbackCallback::setupTo(looper, manager); |
| 136 | |
| 137 | while(true) { |
| 138 | looper->pollAll(-1); |
| 139 | } |
Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 140 | |
| 141 | // should not be reached |
| 142 | return EXIT_FAILURE; |
| 143 | } |