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 "BpBinder"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define LOG_NDEBUG 0
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
200795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/BpBinder.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
220795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/IPCThreadState.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#undef LOGV
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define LOGV(...) fprintf(stderr, __VA_ARGS__)
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectBpBinder::ObjectManager::ObjectManager()
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectBpBinder::ObjectManager::~ObjectManager()
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    kill();
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid BpBinder::ObjectManager::attach(
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const void* objectID, void* object, void* cleanupCookie,
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IBinder::object_cleanup_func func)
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    entry_t e;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    e.object = object;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    e.cleanupCookie = cleanupCookie;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    e.func = func;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mObjects.indexOfKey(objectID) >= 0) {
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                objectID, this,  object);
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mObjects.add(objectID, e);
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid* BpBinder::ObjectManager::find(const void* objectID) const
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const ssize_t i = mObjects.indexOfKey(objectID);
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (i < 0) return NULL;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mObjects.valueAt(i).object;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid BpBinder::ObjectManager::detach(const void* objectID)
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mObjects.removeItem(objectID);
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid BpBinder::ObjectManager::kill()
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mObjects.size();
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("Killing %d objects in manager %p", N, this);
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t i=0; i<N; i++) {
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const entry_t& e = mObjects.valueAt(i);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (e.func != NULL) {
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mObjects.clear();
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectBpBinder::BpBinder(int32_t handle)
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mHandle(handle)
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , mAlive(1)
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , mObitsSent(0)
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , mObituaries(NULL)
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("Creating BpBinder %p handle %d\n", this, mHandle);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IPCThreadState::self()->incWeakHandle(handle);
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
101aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopianbool BpBinder::isDescriptorCached() const {
102aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian    Mutex::Autolock _l(mLock);
103aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian    return mDescriptorCache.size() ? true : false;
104aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian}
105aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian
106aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopianconst String16& BpBinder::getInterfaceDescriptor() const
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
108aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian    if (isDescriptorCached() == false) {
109aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian        Parcel send, reply;
110aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian        // do the IPC without a lock held.
111aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian        status_t err = const_cast<BpBinder*>(this)->transact(
112aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian                INTERFACE_TRANSACTION, send, &reply);
113aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian        if (err == NO_ERROR) {
114aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian            String16 res(reply.readString16());
115aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian            Mutex::Autolock _l(mLock);
116aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian            // mDescriptorCache could have been assigned while the lock was
117aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian            // released.
118aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian            if (mDescriptorCache.size() == 0)
119aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian                mDescriptorCache = res;
120aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian        }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
122aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian
123aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian    // we're returning a reference to a non-static object here. Usually this
124aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian    // is not something smart to do, however, with binder objects it is
125aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian    // (usually) safe because they are reference-counted.
126aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian
127aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian    return mDescriptorCache;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool BpBinder::isBinderAlive() const
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mAlive != 0;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t BpBinder::pingBinder()
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel send;
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel reply;
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = transact(PING_TRANSACTION, send, &reply);
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) return err;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (status_t)reply.readInt32();
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t BpBinder::dump(int fd, const Vector<String16>& args)
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel send;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel reply;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    send.writeFileDescriptor(fd);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t numArgs = args.size();
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    send.writeInt32(numArgs);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t i = 0; i < numArgs; i++) {
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        send.writeString16(args[i]);
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = transact(DUMP_TRANSACTION, send, &reply);
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t BpBinder::transact(
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Once a binder has died, it will never come back to life.
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mAlive) {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t status = IPCThreadState::self()->transact(
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHandle, code, data, reply, flags);
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (status == DEAD_OBJECT) mAlive = 0;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return status;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DEAD_OBJECT;
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t BpBinder::linkToDeath(
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Obituary ob;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ob.recipient = recipient;
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ob.cookie = cookie;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ob.flags = flags;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_ALWAYS_FATAL_IF(recipient == NULL,
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "linkToDeath(): recipient must be non-NULL");
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AutoMutex _l(mLock);
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mObitsSent) {
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mObituaries) {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mObituaries = new Vector<Obituary>;
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!mObituaries) {
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return NO_MEMORY;
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                LOGV("Requesting death notification: %p handle %d\n", this, mHandle);
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                getWeakRefs()->incWeak(this);
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IPCThreadState* self = IPCThreadState::self();
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                self->requestDeathNotification(mHandle, this);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                self->flushCommands();
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ssize_t res = mObituaries->add(ob);
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DEAD_OBJECT;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t BpBinder::unlinkToDeath(
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    wp<DeathRecipient>* outRecipient)
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AutoMutex _l(mLock);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mObitsSent) {
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DEAD_OBJECT;
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mObituaries ? mObituaries->size() : 0;
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t i=0; i<N; i++) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Obituary& obit = mObituaries->itemAt(i);
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((obit.recipient == recipient
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    || (recipient == NULL && obit.cookie == cookie))
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && obit.flags == flags) {
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const uint32_t allFlags = obit.flags|flags;
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (outRecipient != NULL) {
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                *outRecipient = mObituaries->itemAt(i).recipient;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mObituaries->removeAt(i);
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mObituaries->size() == 0) {
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                LOGV("Clearing death notification: %p handle %d\n", this, mHandle);
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IPCThreadState* self = IPCThreadState::self();
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                self->clearDeathNotification(mHandle, this);
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                self->flushCommands();
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                delete mObituaries;
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mObituaries = NULL;
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return NO_ERROR;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NAME_NOT_FOUND;
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid BpBinder::sendObituary()
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this, mHandle, mObitsSent ? "true" : "false");
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mAlive = 0;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mObitsSent) return;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mLock.lock();
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<Obituary>* obits = mObituaries;
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if(obits != NULL) {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IPCThreadState* self = IPCThreadState::self();
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        self->clearDeathNotification(mHandle, this);
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        self->flushCommands();
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mObituaries = NULL;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mObitsSent = 1;
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mLock.unlock();
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("Reporting death of proxy %p for %d recipients\n",
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this, obits ? obits->size() : 0);
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (obits != NULL) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = obits->size();
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            reportOneDeath(obits->itemAt(i));
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete obits;
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid BpBinder::reportOneDeath(const Obituary& obit)
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<DeathRecipient> recipient = obit.recipient.promote();
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("Reporting death to recipient: %p\n", recipient.get());
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (recipient == NULL) return;
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    recipient->binderDied(this);
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid BpBinder::attachObject(
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const void* objectID, void* object, void* cleanupCookie,
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    object_cleanup_func func)
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AutoMutex _l(mLock);
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mObjects.attach(objectID, object, cleanupCookie, func);
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid* BpBinder::findObject(const void* objectID) const
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AutoMutex _l(mLock);
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mObjects.find(objectID);
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid BpBinder::detachObject(const void* objectID)
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AutoMutex _l(mLock);
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mObjects.detach(objectID);
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectBpBinder* BpBinder::remoteBinder()
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return this;
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectBpBinder::~BpBinder()
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IPCThreadState* ipc = IPCThreadState::self();
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mLock.lock();
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<Obituary>* obits = mObituaries;
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if(obits != NULL) {
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ipc) ipc->clearDeathNotification(mHandle, this);
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mObituaries = NULL;
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mLock.unlock();
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (obits != NULL) {
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // XXX Should we tell any remaining DeathRecipient
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // objects that the last strong ref has gone away, so they
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // are no longer linked?
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete obits;
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ipc) {
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ipc->expungeHandle(mHandle, this);
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ipc->decWeakHandle(mHandle);
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid BpBinder::onFirstRef()
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IPCThreadState* ipc = IPCThreadState::self();
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ipc) ipc->incStrongHandle(mHandle);
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid BpBinder::onLastStrongRef(const void* id)
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IF_LOGV() {
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printRefs();
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IPCThreadState* ipc = IPCThreadState::self();
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ipc) ipc->decStrongHandle(mHandle);
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool BpBinder::onIncStrongAttempted(uint32_t flags, const void* id)
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IPCThreadState* ipc = IPCThreadState::self();
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android
366