• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
21 #include <sys/timerfd.h>
22 #include <utils/Looper.h>
23 #include <utils/StrongPointer.h>
24 
25 #include "Access.h"
26 #include "ServiceManager.h"
27 
28 using ::android::Access;
29 using ::android::sp;
30 using ::android::Looper;
31 using ::android::LooperCallback;
32 using ::android::ProcessState;
33 using ::android::IPCThreadState;
34 using ::android::ProcessState;
35 using ::android::ServiceManager;
36 using ::android::os::IServiceManager;
37 using ::android::sp;
38 
39 class BinderCallback : public LooperCallback {
40 public:
setupTo(const sp<Looper> & looper)41     static sp<BinderCallback> setupTo(const sp<Looper>& looper) {
42         sp<BinderCallback> cb = sp<BinderCallback>::make();
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 
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 
handleEvent(int,int,void *)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:
setupTo(const sp<Looper> & looper,const sp<ServiceManager> & manager)67     static sp<ClientCallbackCallback> setupTo(const sp<Looper>& looper, const sp<ServiceManager>& manager) {
68         sp<ClientCallbackCallback> cb = sp<ClientCallbackCallback>::make(manager);
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*/, &timespec, 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 
handleEvent(int fd,int,void *)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:
108     friend sp<ClientCallbackCallback>;
ClientCallbackCallback(const sp<ServiceManager> & manager)109     ClientCallbackCallback(const sp<ServiceManager>& manager) : mManager(manager) {}
110     sp<ServiceManager> mManager;
111 };
112 
main(int argc,char ** argv)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 
120     sp<ProcessState> ps = ProcessState::initWithDriver(driver);
121     ps->setThreadPoolMaxThreadCount(0);
122     ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
123 
124     sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
125     if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
126         LOG(ERROR) << "Could not self register servicemanager";
127     }
128 
129     IPCThreadState::self()->setTheContextObject(manager);
130     ps->becomeContextManager();
131 
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     }
140 
141     // should not be reached
142     return EXIT_FAILURE;
143 }
144