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