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