blob: 2d4e10ddde53460574dc2e30cbc8d9faf5aafb5f [file] [log] [blame]
Mathias Agopian7922fa22009-05-18 15:08:03 -07001/*
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
Mathias Agopian16475702009-05-19 19:08:10 -070021#include <binder/ProcessState.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070022
23#include <utils/Atomic.h>
Mathias Agopian16475702009-05-19 19:08:10 -070024#include <binder/BpBinder.h>
25#include <binder/IPCThreadState.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070026#include <utils/Log.h>
27#include <utils/String8.h>
Mathias Agopian16475702009-05-19 19:08:10 -070028#include <binder/IServiceManager.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070029#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
Rebecca Schultz Zavinba3e5e22009-10-30 18:39:55 -070044#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
Mathias Agopian7922fa22009-05-18 15:08:03 -070045
46static bool gSingleProcess = false;
47
48
49// ---------------------------------------------------------------------------
50
51namespace android {
52
53// Global variables
54int mArgC;
55const char* const* mArgV;
56int mArgLen;
57
58class PoolThread : public Thread
59{
60public:
61 PoolThread(bool isMain)
62 : mIsMain(isMain)
63 {
64 }
65
66protected:
67 virtual bool threadLoop()
68 {
69 IPCThreadState::self()->joinThreadPool(mIsMain);
70 return false;
71 }
72
73 const bool mIsMain;
74};
75
76sp<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
85void ProcessState::setSingleProcess(bool singleProcess)
86{
87 gSingleProcess = singleProcess;
88}
89
90
91void ProcessState::setContextObject(const sp<IBinder>& object)
92{
93 setContextObject(object, String16("default"));
94}
95
96sp<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
105void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
106{
107 AutoMutex _l(mLock);
108 mContexts.add(name, object);
109}
110
111sp<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
147bool ProcessState::supportsProcesses() const
148{
149 return mDriverFD >= 0;
150}
151
152void ProcessState::startThreadPool()
153{
154 AutoMutex _l(mLock);
155 if (!mThreadPoolStarted) {
156 mThreadPoolStarted = true;
157 spawnPooledThread(true);
158 }
159}
160
161bool ProcessState::isContextManager(void) const
162{
163 return mManagesContexts;
164}
165
166bool 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
195ProcessState::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
208sp<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
238wp<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
269void 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
281void 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
293int ProcessState::getArgC() const
294{
295 return mArgC;
296}
297
298const char* const* ProcessState::getArgV() const
299{
300 return mArgV;
301}
302
303void 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
311void 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
323static 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
363ProcessState::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
394ProcessState::~ProcessState()
395{
396}
397
398}; // namespace android