ProcessState.cpp revision a0a40883d0f4bdc0694b236353ad66a4b4ca92fa
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "ProcessState" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/process_name.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 210795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/ProcessState.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Atomic.h> 240795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/BpBinder.h> 250795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/IPCThreadState.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String8.h> 280795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/IServiceManager.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String8.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/threads.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3225ba5b6564224dceefa086b5c439ef28dad530caMathias Agopian#include <private/binder/binder_module.h> 3325ba5b6564224dceefa086b5c439ef28dad530caMathias Agopian#include <private/binder/Static.h> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h> 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/ioctl.h> 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/mman.h> 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h> 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44a0a40883d0f4bdc0694b236353ad66a4b4ca92faRebecca Schultz Zavin#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2)) 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool gSingleProcess = false; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Global variables 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint mArgC; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* const* mArgV; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint mArgLen; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass PoolThread : public Thread 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PoolThread(bool isMain) 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mIsMain(isMain) 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprotected: 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual bool threadLoop() 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IPCThreadState::self()->joinThreadPool(mIsMain); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool mIsMain; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ProcessState> ProcessState::self() 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (gProcess != NULL) return gProcess; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(gProcessMutex); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (gProcess == NULL) gProcess = new ProcessState; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return gProcess; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ProcessState::setSingleProcess(bool singleProcess) 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gSingleProcess = singleProcess; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ProcessState::setContextObject(const sp<IBinder>& object) 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setContextObject(object, String16("default")); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller) 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (supportsProcesses()) { 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getStrongProxyForHandle(0); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getContextObject(String16("default"), caller); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ProcessState::setContextObject(const sp<IBinder>& object, const String16& name) 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(mLock); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContexts.add(name, object); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller) 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.lock(); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IBinder> object( 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.unlock(); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Getting context object %s for %p\n", String8(name).string(), caller.get()); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (object != NULL) return object; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't attempt to retrieve contexts if we manage them 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mManagesContexts) { 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("getContextObject(%s) failed, but we manage the contexts!\n", 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(name).string()); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Parcel data, reply; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // no interface token on this magic transaction 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data.writeString16(name); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data.writeStrongBinder(caller); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == NO_ERROR) { 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project object = reply.readStrongBinder(); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ipc->flushCommands(); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (object != NULL) setContextObject(object, name); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return object; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ProcessState::supportsProcesses() const 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDriverFD >= 0; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ProcessState::startThreadPool() 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(mLock); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mThreadPoolStarted) { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThreadPoolStarted = true; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project spawnPooledThread(true); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ProcessState::isContextManager(void) const 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mManagesContexts; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData) 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mManagesContexts) { 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(mLock); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBinderContextCheckFunc = checkFunc; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBinderContextUserData = userData; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDriverFD >= 0) { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int dummy = 0; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(HAVE_ANDROID_OS) 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = INVALID_OPERATION; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == 0) { 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mManagesContexts = true; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (result == -1) { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBinderContextCheckFunc = NULL; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBinderContextUserData = NULL; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno)); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If there is no driver, our only world is the local 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // process so we can always become the context manager there. 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mManagesContexts = true; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mManagesContexts; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle) 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N=mHandleToObject.size(); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N <= (size_t)handle) { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle_entry e; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e.binder = NULL; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e.refs = NULL; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = mHandleToObject.insertAt(e, N, handle+1-N); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < NO_ERROR) return NULL; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return &mHandleToObject.editItemAt(handle); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IBinder> result; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(mLock); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle_entry* e = lookupHandleLocked(handle); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (e != NULL) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We need to create a new BpBinder if there isn't currently one, OR we 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // are unable to acquire a weak reference on this current one. See comment 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in getWeakProxyForHandle() for more info about this. 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder* b = e->binder; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (b == NULL || !e->refs->attemptIncWeak(this)) { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = new BpBinder(handle); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e->binder = b; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (b) e->refs = b->getWeakRefs(); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = b; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This little bit of nastyness is to allow us to add a primary 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reference to the remote proxy when this team doesn't have one 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // but another team is sending the handle to us. 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result.force_set(b); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e->refs->decWeak(this); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectwp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle) 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wp<IBinder> result; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(mLock); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle_entry* e = lookupHandleLocked(handle); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (e != NULL) { 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We need to create a new BpBinder if there isn't currently one, OR we 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // are unable to acquire a weak reference on this current one. The 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // attemptIncWeak() is safe because we know the BpBinder destructor will always 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // call expungeHandle(), which acquires the same lock we are holding now. 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We need to do this because there is a race condition between someone 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // releasing a reference on this BpBinder, and a new reference on its handle 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // arriving from the driver. 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder* b = e->binder; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (b == NULL || !e->refs->attemptIncWeak(this)) { 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = new BpBinder(handle); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = b; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e->binder = b; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (b) e->refs = b->getWeakRefs(); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = b; 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e->refs->decWeak(this); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ProcessState::expungeHandle(int32_t handle, IBinder* binder) 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(mLock); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle_entry* e = lookupHandleLocked(handle); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This handle may have already been replaced with a new BpBinder 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (if someone failed the AttemptIncWeak() above); we don't want 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to overwrite it. 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (e && e->binder == binder) e->binder = NULL; 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ProcessState::setArgs(int argc, const char* const argv[]) 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mArgC = argc; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mArgV = (const char **)argv; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mArgLen = 0; 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<argc; i++) { 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mArgLen += strlen(argv[i]) + 1; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mArgLen--; 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint ProcessState::getArgC() const 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mArgC; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* const* ProcessState::getArgV() const 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mArgV; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ProcessState::setArgV0(const char* txt) 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mArgV != NULL) { 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strncpy((char*)mArgV[0], txt, mArgLen); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set_process_name(txt); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ProcessState::spawnPooledThread(bool isMain) 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mThreadPoolStarted) { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t s = android_atomic_add(1, &mThreadPoolSeq); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char buf[32]; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(buf, "Binder Thread #%d", s); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("Spawning new pooled thread, name=%s\n", buf); 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<Thread> t = new PoolThread(isMain); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->run(buf); 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int open_driver() 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (gSingleProcess) { 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd = open("/dev/binder", O_RDWR); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd >= 0) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fcntl(fd, F_SETFD, FD_CLOEXEC); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int vers; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(HAVE_ANDROID_OS) 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = ioctl(fd, BINDER_VERSION, &vers); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = -1; 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project errno = EPERM; 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == -1) { 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Binder ioctl to obtain version failed: %s", strerror(errno)); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(fd); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = -1; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) { 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Binder driver protocol does not match user space protocol!"); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(fd); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = -1; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(HAVE_ANDROID_OS) 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t maxThreads = 15; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == -1) { 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Binder ioctl to set max threads failed: %s", strerror(errno)); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno)); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectProcessState::ProcessState() 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mDriverFD(open_driver()) 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mVMStart(MAP_FAILED) 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mManagesContexts(false) 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mBinderContextCheckFunc(NULL) 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mBinderContextUserData(NULL) 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mThreadPoolStarted(false) 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mThreadPoolSeq(1) 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDriverFD >= 0) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // XXX Ideally, there should be a specific define for whether we 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // have mmap (or whether we could possibly have the kernel module 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // availabla). 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if !defined(HAVE_WIN32_IPC) 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mmap the binder, providing a chunk of virtual address space to receive transactions. 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVMStart == MAP_FAILED) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // *sigh* 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Using /dev/binder failed: unable to mmap transaction memory.\n"); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(mDriverFD); 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDriverFD = -1; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDriverFD = -1; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDriverFD < 0) { 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Need to run without the driver, starting our own thread pool. 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectProcessState::~ProcessState() 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 399