1 /*
2 * Copyright (C) 2005 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 #define LOG_TAG "ProcessState"
18
19 #include <cutils/process_name.h>
20
21 #include <binder/ProcessState.h>
22
23 #include <utils/Atomic.h>
24 #include <binder/BpBinder.h>
25 #include <binder/IPCThreadState.h>
26 #include <utils/Log.h>
27 #include <utils/String8.h>
28 #include <binder/IServiceManager.h>
29 #include <utils/String8.h>
30 #include <utils/threads.h>
31
32 #include <private/binder/binder_module.h>
33 #include <private/binder/Static.h>
34
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <sys/ioctl.h>
41 #include <sys/mman.h>
42 #include <sys/stat.h>
43
44 #define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
45
46 static bool gSingleProcess = false;
47
48
49 // ---------------------------------------------------------------------------
50
51 namespace android {
52
53 // Global variables
54 int mArgC;
55 const char* const* mArgV;
56 int mArgLen;
57
58 class PoolThread : public Thread
59 {
60 public:
PoolThread(bool isMain)61 PoolThread(bool isMain)
62 : mIsMain(isMain)
63 {
64 }
65
66 protected:
threadLoop()67 virtual bool threadLoop()
68 {
69 IPCThreadState::self()->joinThreadPool(mIsMain);
70 return false;
71 }
72
73 const bool mIsMain;
74 };
75
self()76 sp<ProcessState> ProcessState::self()
77 {
78 if (gProcess != NULL) return gProcess;
79
80 AutoMutex _l(gProcessMutex);
81 if (gProcess == NULL) gProcess = new ProcessState;
82 return gProcess;
83 }
84
setSingleProcess(bool singleProcess)85 void ProcessState::setSingleProcess(bool singleProcess)
86 {
87 gSingleProcess = singleProcess;
88 }
89
90
setContextObject(const sp<IBinder> & object)91 void ProcessState::setContextObject(const sp<IBinder>& object)
92 {
93 setContextObject(object, String16("default"));
94 }
95
getContextObject(const sp<IBinder> & caller)96 sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
97 {
98 if (supportsProcesses()) {
99 return getStrongProxyForHandle(0);
100 } else {
101 return getContextObject(String16("default"), caller);
102 }
103 }
104
setContextObject(const sp<IBinder> & object,const String16 & name)105 void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
106 {
107 AutoMutex _l(mLock);
108 mContexts.add(name, object);
109 }
110
getContextObject(const String16 & name,const sp<IBinder> & caller)111 sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
112 {
113 mLock.lock();
114 sp<IBinder> object(
115 mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
116 mLock.unlock();
117
118 //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
119
120 if (object != NULL) return object;
121
122 // Don't attempt to retrieve contexts if we manage them
123 if (mManagesContexts) {
124 LOGE("getContextObject(%s) failed, but we manage the contexts!\n",
125 String8(name).string());
126 return NULL;
127 }
128
129 IPCThreadState* ipc = IPCThreadState::self();
130 {
131 Parcel data, reply;
132 // no interface token on this magic transaction
133 data.writeString16(name);
134 data.writeStrongBinder(caller);
135 status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0);
136 if (result == NO_ERROR) {
137 object = reply.readStrongBinder();
138 }
139 }
140
141 ipc->flushCommands();
142
143 if (object != NULL) setContextObject(object, name);
144 return object;
145 }
146
supportsProcesses() const147 bool ProcessState::supportsProcesses() const
148 {
149 return mDriverFD >= 0;
150 }
151
startThreadPool()152 void ProcessState::startThreadPool()
153 {
154 AutoMutex _l(mLock);
155 if (!mThreadPoolStarted) {
156 mThreadPoolStarted = true;
157 spawnPooledThread(true);
158 }
159 }
160
isContextManager(void) const161 bool ProcessState::isContextManager(void) const
162 {
163 return mManagesContexts;
164 }
165
becomeContextManager(context_check_func checkFunc,void * userData)166 bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
167 {
168 if (!mManagesContexts) {
169 AutoMutex _l(mLock);
170 mBinderContextCheckFunc = checkFunc;
171 mBinderContextUserData = userData;
172 if (mDriverFD >= 0) {
173 int dummy = 0;
174 #if defined(HAVE_ANDROID_OS)
175 status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
176 #else
177 status_t result = INVALID_OPERATION;
178 #endif
179 if (result == 0) {
180 mManagesContexts = true;
181 } else if (result == -1) {
182 mBinderContextCheckFunc = NULL;
183 mBinderContextUserData = NULL;
184 LOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
185 }
186 } else {
187 // If there is no driver, our only world is the local
188 // process so we can always become the context manager there.
189 mManagesContexts = true;
190 }
191 }
192 return mManagesContexts;
193 }
194
lookupHandleLocked(int32_t handle)195 ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
196 {
197 const size_t N=mHandleToObject.size();
198 if (N <= (size_t)handle) {
199 handle_entry e;
200 e.binder = NULL;
201 e.refs = NULL;
202 status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
203 if (err < NO_ERROR) return NULL;
204 }
205 return &mHandleToObject.editItemAt(handle);
206 }
207
getStrongProxyForHandle(int32_t handle)208 sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
209 {
210 sp<IBinder> result;
211
212 AutoMutex _l(mLock);
213
214 handle_entry* e = lookupHandleLocked(handle);
215
216 if (e != NULL) {
217 // We need to create a new BpBinder if there isn't currently one, OR we
218 // are unable to acquire a weak reference on this current one. See comment
219 // in getWeakProxyForHandle() for more info about this.
220 IBinder* b = e->binder;
221 if (b == NULL || !e->refs->attemptIncWeak(this)) {
222 b = new BpBinder(handle);
223 e->binder = b;
224 if (b) e->refs = b->getWeakRefs();
225 result = b;
226 } else {
227 // This little bit of nastyness is to allow us to add a primary
228 // reference to the remote proxy when this team doesn't have one
229 // but another team is sending the handle to us.
230 result.force_set(b);
231 e->refs->decWeak(this);
232 }
233 }
234
235 return result;
236 }
237
getWeakProxyForHandle(int32_t handle)238 wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
239 {
240 wp<IBinder> result;
241
242 AutoMutex _l(mLock);
243
244 handle_entry* e = lookupHandleLocked(handle);
245
246 if (e != NULL) {
247 // We need to create a new BpBinder if there isn't currently one, OR we
248 // are unable to acquire a weak reference on this current one. The
249 // attemptIncWeak() is safe because we know the BpBinder destructor will always
250 // call expungeHandle(), which acquires the same lock we are holding now.
251 // We need to do this because there is a race condition between someone
252 // releasing a reference on this BpBinder, and a new reference on its handle
253 // arriving from the driver.
254 IBinder* b = e->binder;
255 if (b == NULL || !e->refs->attemptIncWeak(this)) {
256 b = new BpBinder(handle);
257 result = b;
258 e->binder = b;
259 if (b) e->refs = b->getWeakRefs();
260 } else {
261 result = b;
262 e->refs->decWeak(this);
263 }
264 }
265
266 return result;
267 }
268
expungeHandle(int32_t handle,IBinder * binder)269 void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
270 {
271 AutoMutex _l(mLock);
272
273 handle_entry* e = lookupHandleLocked(handle);
274
275 // This handle may have already been replaced with a new BpBinder
276 // (if someone failed the AttemptIncWeak() above); we don't want
277 // to overwrite it.
278 if (e && e->binder == binder) e->binder = NULL;
279 }
280
setArgs(int argc,const char * const argv[])281 void ProcessState::setArgs(int argc, const char* const argv[])
282 {
283 mArgC = argc;
284 mArgV = (const char **)argv;
285
286 mArgLen = 0;
287 for (int i=0; i<argc; i++) {
288 mArgLen += strlen(argv[i]) + 1;
289 }
290 mArgLen--;
291 }
292
getArgC() const293 int ProcessState::getArgC() const
294 {
295 return mArgC;
296 }
297
getArgV() const298 const char* const* ProcessState::getArgV() const
299 {
300 return mArgV;
301 }
302
setArgV0(const char * txt)303 void ProcessState::setArgV0(const char* txt)
304 {
305 if (mArgV != NULL) {
306 strncpy((char*)mArgV[0], txt, mArgLen);
307 set_process_name(txt);
308 }
309 }
310
spawnPooledThread(bool isMain)311 void ProcessState::spawnPooledThread(bool isMain)
312 {
313 if (mThreadPoolStarted) {
314 int32_t s = android_atomic_add(1, &mThreadPoolSeq);
315 char buf[32];
316 sprintf(buf, "Binder Thread #%d", s);
317 LOGV("Spawning new pooled thread, name=%s\n", buf);
318 sp<Thread> t = new PoolThread(isMain);
319 t->run(buf);
320 }
321 }
322
open_driver()323 static int open_driver()
324 {
325 if (gSingleProcess) {
326 return -1;
327 }
328
329 int fd = open("/dev/binder", O_RDWR);
330 if (fd >= 0) {
331 fcntl(fd, F_SETFD, FD_CLOEXEC);
332 int vers;
333 #if defined(HAVE_ANDROID_OS)
334 status_t result = ioctl(fd, BINDER_VERSION, &vers);
335 #else
336 status_t result = -1;
337 errno = EPERM;
338 #endif
339 if (result == -1) {
340 LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
341 close(fd);
342 fd = -1;
343 }
344 if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
345 LOGE("Binder driver protocol does not match user space protocol!");
346 close(fd);
347 fd = -1;
348 }
349 #if defined(HAVE_ANDROID_OS)
350 size_t maxThreads = 15;
351 result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
352 if (result == -1) {
353 LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
354 }
355 #endif
356
357 } else {
358 LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
359 }
360 return fd;
361 }
362
ProcessState()363 ProcessState::ProcessState()
364 : mDriverFD(open_driver())
365 , mVMStart(MAP_FAILED)
366 , mManagesContexts(false)
367 , mBinderContextCheckFunc(NULL)
368 , mBinderContextUserData(NULL)
369 , mThreadPoolStarted(false)
370 , mThreadPoolSeq(1)
371 {
372 if (mDriverFD >= 0) {
373 // XXX Ideally, there should be a specific define for whether we
374 // have mmap (or whether we could possibly have the kernel module
375 // availabla).
376 #if !defined(HAVE_WIN32_IPC)
377 // mmap the binder, providing a chunk of virtual address space to receive transactions.
378 mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
379 if (mVMStart == MAP_FAILED) {
380 // *sigh*
381 LOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
382 close(mDriverFD);
383 mDriverFD = -1;
384 }
385 #else
386 mDriverFD = -1;
387 #endif
388 }
389 if (mDriverFD < 0) {
390 // Need to run without the driver, starting our own thread pool.
391 }
392 }
393
~ProcessState()394 ProcessState::~ProcessState()
395 {
396 }
397
398 }; // namespace android
399