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