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