• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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