ProcessState.cpp revision 102d539a4c6e70ec2403bfd2bfef3a3373da15ac
18eb69d60c09c1c4683066a94c889df28d0e9d233James Dong/* 28eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * Copyright (C) 2005 The Android Open Source Project 38eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * 48eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 58eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * you may not use this file except in compliance with the License. 68eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * You may obtain a copy of the License at 78eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * 88eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * http://www.apache.org/licenses/LICENSE-2.0 98eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * 108eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * Unless required by applicable law or agreed to in writing, software 118eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * distributed under the License is distributed on an "AS IS" BASIS, 128eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * See the License for the specific language governing permissions and 148eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * limitations under the License. 158eb69d60c09c1c4683066a94c889df28d0e9d233James Dong */ 168eb69d60c09c1c4683066a94c889df28d0e9d233James Dong 1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "ProcessState" 1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/process_name.h> 2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/ProcessState.h> 2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Atomic.h> 2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/BpBinder.h> 2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h> 2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h> 2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String8.h> 2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h> 2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String8.h> 3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/threads.h> 3165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <private/binder/binder_module.h> 3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <private/binder/Static.h> 3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <errno.h> 3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <fcntl.h> 3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <stdio.h> 3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <stdlib.h> 3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <unistd.h> 4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/ioctl.h> 4165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/mman.h> 4265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/stat.h> 4365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2)) 4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// --------------------------------------------------------------------------- 4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android { 5065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Global variables 5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianint mArgC; 5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianconst char* const* mArgV; 5465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianint mArgLen; 5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianclass PoolThread : public Thread 5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianpublic: 5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian PoolThread(bool isMain) 6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian : mIsMain(isMain) 6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprotected: 6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian virtual bool threadLoop() 6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 6765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IPCThreadState::self()->joinThreadPool(mIsMain); 6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return false; 6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 7065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 7165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const bool mIsMain; 7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; 7365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 7465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<ProcessState> ProcessState::self() 7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 7665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (gProcess != NULL) return gProcess; 7765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 7865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AutoMutex _l(gProcessMutex); 7965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (gProcess == NULL) gProcess = new ProcessState; 8065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return gProcess; 8165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 8265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 8365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ProcessState::setContextObject(const sp<IBinder>& object) 8465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 8565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian setContextObject(object, String16("default")); 8665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 8865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller) 8965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 9065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return getStrongProxyForHandle(0); 9165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 9265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 9365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ProcessState::setContextObject(const sp<IBinder>& object, const String16& name) 9465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 9565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AutoMutex _l(mLock); 9665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mContexts.add(name, object); 9765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 9865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 9965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller) 10065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 10165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 10265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<IBinder> object( 10365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL); 10465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 10565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 10665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian //printf("Getting context object %s for %p\n", String8(name).string(), caller.get()); 10765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 10865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (object != NULL) return object; 10965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 11065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Don't attempt to retrieve contexts if we manage them 11165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mManagesContexts) { 11265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ALOGE("getContextObject(%s) failed, but we manage the contexts!\n", 11365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8(name).string()); 11465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 11565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 11665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 11765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 11865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 11965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Parcel data, reply; 12065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // no interface token on this magic transaction 12165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data.writeString16(name); 12265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data.writeStrongBinder(caller); 12365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0); 12465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result == NO_ERROR) { 12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian object = reply.readStrongBinder(); 12665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 12765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 12865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 12965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ipc->flushCommands(); 13065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 13165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (object != NULL) setContextObject(object, name); 13265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return object; 13365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 13465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 13565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ProcessState::startThreadPool() 13665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 13765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AutoMutex _l(mLock); 13865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!mThreadPoolStarted) { 13965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mThreadPoolStarted = true; 14065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian spawnPooledThread(true); 14165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 14265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 14365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 14465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool ProcessState::isContextManager(void) const 14565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 14665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mManagesContexts; 14765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 14865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 14965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData) 15065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 15165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!mManagesContexts) { 15265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AutoMutex _l(mLock); 15365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mBinderContextCheckFunc = checkFunc; 15465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mBinderContextUserData = userData; 15565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 15665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int dummy = 0; 15765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy); 15865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result == 0) { 15965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mManagesContexts = true; 16065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else if (result == -1) { 16165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mBinderContextCheckFunc = NULL; 16265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mBinderContextUserData = NULL; 16365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno)); 16465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 16565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 16665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mManagesContexts; 16765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 16865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 16965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle) 17065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 17165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t N=mHandleToObject.size(); 17265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (N <= (size_t)handle) { 17365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian handle_entry e; 17465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian e.binder = NULL; 17565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian e.refs = NULL; 17665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t err = mHandleToObject.insertAt(e, N, handle+1-N); 17765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (err < NO_ERROR) return NULL; 17865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 17965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return &mHandleToObject.editItemAt(handle); 18065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 18165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 18265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) 18365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 18465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<IBinder> result; 18565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 18665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AutoMutex _l(mLock); 18765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 18865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian handle_entry* e = lookupHandleLocked(handle); 18965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 19065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (e != NULL) { 19165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // We need to create a new BpBinder if there isn't currently one, OR we 19265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // are unable to acquire a weak reference on this current one. See comment 19365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // in getWeakProxyForHandle() for more info about this. 19465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IBinder* b = e->binder; 19565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (b == NULL || !e->refs->attemptIncWeak(this)) { 19665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian b = new BpBinder(handle); 19765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian e->binder = b; 19865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (b) e->refs = b->getWeakRefs(); 19965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = b; 20065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 20165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // This little bit of nastyness is to allow us to add a primary 20265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // reference to the remote proxy when this team doesn't have one 20365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // but another team is sending the handle to us. 20465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.force_set(b); 20565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian e->refs->decWeak(this); 20665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 20965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 21065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 21165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 21265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianwp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle) 21365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 21465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian wp<IBinder> result; 21565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 21665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AutoMutex _l(mLock); 21765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 21865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian handle_entry* e = lookupHandleLocked(handle); 21965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 22065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (e != NULL) { 22165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // We need to create a new BpBinder if there isn't currently one, OR we 22265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // are unable to acquire a weak reference on this current one. The 22365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // attemptIncWeak() is safe because we know the BpBinder destructor will always 22465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // call expungeHandle(), which acquires the same lock we are holding now. 22565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // We need to do this because there is a race condition between someone 22665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // releasing a reference on this BpBinder, and a new reference on its handle 22765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // arriving from the driver. 22865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IBinder* b = e->binder; 22965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (b == NULL || !e->refs->attemptIncWeak(this)) { 23065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian b = new BpBinder(handle); 23165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = b; 23265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian e->binder = b; 23365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (b) e->refs = b->getWeakRefs(); 23465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 23565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = b; 23665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian e->refs->decWeak(this); 23765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 23865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 23965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 24065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 24165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 24265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 24365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ProcessState::expungeHandle(int32_t handle, IBinder* binder) 24465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 24565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AutoMutex _l(mLock); 24665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 24765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian handle_entry* e = lookupHandleLocked(handle); 24865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // This handle may have already been replaced with a new BpBinder 25065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // (if someone failed the AttemptIncWeak() above); we don't want 25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // to overwrite it. 25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (e && e->binder == binder) e->binder = NULL; 25365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 25565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ProcessState::setArgs(int argc, const char* const argv[]) 25665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 25765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mArgC = argc; 25865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mArgV = (const char **)argv; 25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 26065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mArgLen = 0; 26165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i=0; i<argc; i++) { 26265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mArgLen += strlen(argv[i]) + 1; 26365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 26465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mArgLen--; 26565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 26665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 26765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianint ProcessState::getArgC() const 26865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mArgC; 27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 27165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 27265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianconst char* const* ProcessState::getArgV() const 27365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 27465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mArgV; 27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 27665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 27765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ProcessState::setArgV0(const char* txt) 27865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mArgV != NULL) { 28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian strncpy((char*)mArgV[0], txt, mArgLen); 28165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian set_process_name(txt); 28265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 28365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 28565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ProcessState::spawnPooledThread(bool isMain) 28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 28765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mThreadPoolStarted) { 28865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t s = android_atomic_add(1, &mThreadPoolSeq); 28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buf[16]; 29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buf, sizeof(buf), "Binder_%X", s); 29165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ALOGV("Spawning new pooled thread, name=%s\n", buf); 29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Thread> t = new PoolThread(isMain); 29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian t->run(buf); 29465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 29765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int open_driver() 29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int fd = open("/dev/binder", O_RDWR); 30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (fd >= 0) { 30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian fcntl(fd, F_SETFD, FD_CLOEXEC); 30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int vers; 30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = ioctl(fd, BINDER_VERSION, &vers); 30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result == -1) { 30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno)); 30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian close(fd); 30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian fd = -1; 30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) { 31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ALOGE("Binder driver protocol does not match user space protocol!"); 31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian close(fd); 31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian fd = -1; 31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian size_t maxThreads = 15; 31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); 31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result == -1) { 31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno)); 31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno)); 32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return fd; 32365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianProcessState::ProcessState() 32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian : mDriverFD(open_driver()) 32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian , mVMStart(MAP_FAILED) 32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian , mManagesContexts(false) 32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian , mBinderContextCheckFunc(NULL) 33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian , mBinderContextUserData(NULL) 33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian , mThreadPoolStarted(false) 33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian , mThreadPoolSeq(1) 33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mDriverFD >= 0) { 33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // XXX Ideally, there should be a specific define for whether we 33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // have mmap (or whether we could possibly have the kernel module 33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // availabla). 33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#if !defined(HAVE_WIN32_IPC) 33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // mmap the binder, providing a chunk of virtual address space to receive transactions. 34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); 34165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mVMStart == MAP_FAILED) { 34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // *sigh* 34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n"); 34465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian close(mDriverFD); 34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mDriverFD = -1; 34665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 34765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#else 34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mDriverFD = -1; 34965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#endif 35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 35265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating."); 35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianProcessState::~ProcessState() 35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android 36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian