1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define LOG_TAG "BpBinder"
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project//#define LOG_NDEBUG 0
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/BpBinder.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
2323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <binder/IResultReceiver.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
286807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block//#undef ALOGV
296807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpBinder::ObjectManager::ObjectManager()
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpBinder::ObjectManager::~ObjectManager()
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    kill();
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpBinder::ObjectManager::attach(
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const void* objectID, void* object, void* cleanupCookie,
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    IBinder::object_cleanup_func func)
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    entry_t e;
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    e.object = object;
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    e.cleanupCookie = cleanupCookie;
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    e.func = func;
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mObjects.indexOfKey(objectID) >= 0) {
54e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                objectID, this,  object);
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mObjects.add(objectID, e);
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* BpBinder::ObjectManager::find(const void* objectID) const
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t i = mObjects.indexOfKey(objectID);
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (i < 0) return NULL;
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mObjects.valueAt(i).object;
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpBinder::ObjectManager::detach(const void* objectID)
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mObjects.removeItem(objectID);
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpBinder::ObjectManager::kill()
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = mObjects.size();
77d4ecccfd206604a9b2d8a1220844fc2df85a5998Mark Salyzyn    ALOGV("Killing %zu objects in manager %p", N, this);
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0; i<N; i++) {
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const entry_t& e = mObjects.valueAt(i);
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (e.func != NULL) {
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mObjects.clear();
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpBinder::BpBinder(int32_t handle)
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHandle(handle)
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    , mAlive(1)
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    , mObitsSent(0)
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    , mObituaries(NULL)
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
966807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block    ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    IPCThreadState::self()->incWeakHandle(handle);
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10283c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopianbool BpBinder::isDescriptorCached() const {
10383c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian    Mutex::Autolock _l(mLock);
10483c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian    return mDescriptorCache.size() ? true : false;
10583c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian}
10683c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian
10783c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopianconst String16& BpBinder::getInterfaceDescriptor() const
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10983c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian    if (isDescriptorCached() == false) {
11083c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian        Parcel send, reply;
11183c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian        // do the IPC without a lock held.
11283c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian        status_t err = const_cast<BpBinder*>(this)->transact(
11383c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian                INTERFACE_TRANSACTION, send, &reply);
11483c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian        if (err == NO_ERROR) {
11583c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian            String16 res(reply.readString16());
11683c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian            Mutex::Autolock _l(mLock);
11783c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian            // mDescriptorCache could have been assigned while the lock was
11883c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian            // released.
11983c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian            if (mDescriptorCache.size() == 0)
12083c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian                mDescriptorCache = res;
12183c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian        }
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
123d4ecccfd206604a9b2d8a1220844fc2df85a5998Mark Salyzyn
12483c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian    // we're returning a reference to a non-static object here. Usually this
125d4ecccfd206604a9b2d8a1220844fc2df85a5998Mark Salyzyn    // is not something smart to do, however, with binder objects it is
12683c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian    // (usually) safe because they are reference-counted.
127d4ecccfd206604a9b2d8a1220844fc2df85a5998Mark Salyzyn
12883c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian    return mDescriptorCache;
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool BpBinder::isBinderAlive() const
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mAlive != 0;
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BpBinder::pingBinder()
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Parcel send;
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Parcel reply;
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = transact(PING_TRANSACTION, send, &reply);
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err != NO_ERROR) return err;
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (status_t)reply.readInt32();
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BpBinder::dump(int fd, const Vector<String16>& args)
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Parcel send;
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Parcel reply;
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    send.writeFileDescriptor(fd);
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t numArgs = args.size();
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    send.writeInt32(numArgs);
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i = 0; i < numArgs; i++) {
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        send.writeString16(args[i]);
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = transact(DUMP_TRANSACTION, send, &reply);
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BpBinder::transact(
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Once a binder has died, it will never come back to life.
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mAlive) {
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        status_t status = IPCThreadState::self()->transact(
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mHandle, code, data, reply, flags);
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (status == DEAD_OBJECT) mAlive = 0;
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return status;
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return DEAD_OBJECT;
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BpBinder::linkToDeath(
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Obituary ob;
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ob.recipient = recipient;
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ob.cookie = cookie;
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ob.flags = flags;
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOG_ALWAYS_FATAL_IF(recipient == NULL,
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        "linkToDeath(): recipient must be non-NULL");
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        AutoMutex _l(mLock);
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!mObitsSent) {
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!mObituaries) {
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mObituaries = new Vector<Obituary>;
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (!mObituaries) {
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    return NO_MEMORY;
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1946807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                getWeakRefs()->incWeak(this);
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState* self = IPCThreadState::self();
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                self->requestDeathNotification(mHandle, this);
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                self->flushCommands();
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ssize_t res = mObituaries->add(ob);
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return DEAD_OBJECT;
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BpBinder::unlinkToDeath(
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    wp<DeathRecipient>* outRecipient)
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    AutoMutex _l(mLock);
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mObitsSent) {
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return DEAD_OBJECT;
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = mObituaries ? mObituaries->size() : 0;
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0; i<N; i++) {
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Obituary& obit = mObituaries->itemAt(i);
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((obit.recipient == recipient
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    || (recipient == NULL && obit.cookie == cookie))
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                && obit.flags == flags) {
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (outRecipient != NULL) {
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                *outRecipient = mObituaries->itemAt(i).recipient;
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mObituaries->removeAt(i);
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (mObituaries->size() == 0) {
2296807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState* self = IPCThreadState::self();
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                self->clearDeathNotification(mHandle, this);
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                self->flushCommands();
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                delete mObituaries;
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mObituaries = NULL;
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NAME_NOT_FOUND;
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpBinder::sendObituary()
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2456807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block    ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        this, mHandle, mObitsSent ? "true" : "false");
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mAlive = 0;
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mObitsSent) return;
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mLock.lock();
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Vector<Obituary>* obits = mObituaries;
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if(obits != NULL) {
2546807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        IPCThreadState* self = IPCThreadState::self();
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        self->clearDeathNotification(mHandle, this);
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        self->flushCommands();
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mObituaries = NULL;
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mObitsSent = 1;
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mLock.unlock();
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
263d4ecccfd206604a9b2d8a1220844fc2df85a5998Mark Salyzyn    ALOGV("Reporting death of proxy %p for %zu recipients\n",
264d4ecccfd206604a9b2d8a1220844fc2df85a5998Mark Salyzyn        this, obits ? obits->size() : 0U);
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (obits != NULL) {
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t N = obits->size();
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0; i<N; i++) {
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            reportOneDeath(obits->itemAt(i));
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        delete obits;
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpBinder::reportOneDeath(const Obituary& obit)
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<DeathRecipient> recipient = obit.recipient.promote();
2796807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block    ALOGV("Reporting death to recipient: %p\n", recipient.get());
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (recipient == NULL) return;
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    recipient->binderDied(this);
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpBinder::attachObject(
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const void* objectID, void* object, void* cleanupCookie,
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    object_cleanup_func func)
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    AutoMutex _l(mLock);
2916807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block    ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mObjects.attach(objectID, object, cleanupCookie, func);
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* BpBinder::findObject(const void* objectID) const
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    AutoMutex _l(mLock);
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mObjects.find(objectID);
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpBinder::detachObject(const void* objectID)
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    AutoMutex _l(mLock);
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mObjects.detach(objectID);
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpBinder* BpBinder::remoteBinder()
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return this;
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpBinder::~BpBinder()
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3146807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block    ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    IPCThreadState* ipc = IPCThreadState::self();
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mLock.lock();
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Vector<Obituary>* obits = mObituaries;
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if(obits != NULL) {
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (ipc) ipc->clearDeathNotification(mHandle, this);
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mObituaries = NULL;
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mLock.unlock();
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (obits != NULL) {
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // XXX Should we tell any remaining DeathRecipient
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // objects that the last strong ref has gone away, so they
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // are no longer linked?
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        delete obits;
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ipc) {
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ipc->expungeHandle(mHandle, this);
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ipc->decWeakHandle(mHandle);
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpBinder::onFirstRef()
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3416807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block    ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    IPCThreadState* ipc = IPCThreadState::self();
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ipc) ipc->incStrongHandle(mHandle);
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3466f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Crossvoid BpBinder::onLastStrongRef(const void* /*id*/)
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3486807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block    ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
3496807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block    IF_ALOGV() {
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        printRefs();
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    IPCThreadState* ipc = IPCThreadState::self();
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ipc) ipc->decStrongHandle(mHandle);
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3566f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Crossbool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3586807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block    ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    IPCThreadState* ipc = IPCThreadState::self();
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
366