BpBinder.cpp revision d4ecccfd206604a9b2d8a1220844fc2df85a5998
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>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
276807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block//#undef ALOGV
286807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpBinder::ObjectManager::ObjectManager()
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpBinder::ObjectManager::~ObjectManager()
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    kill();
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpBinder::ObjectManager::attach(
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const void* objectID, void* object, void* cleanupCookie,
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    IBinder::object_cleanup_func func)
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    entry_t e;
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    e.object = object;
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    e.cleanupCookie = cleanupCookie;
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    e.func = func;
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mObjects.indexOfKey(objectID) >= 0) {
53e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                objectID, this,  object);
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mObjects.add(objectID, e);
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* BpBinder::ObjectManager::find(const void* objectID) const
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t i = mObjects.indexOfKey(objectID);
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (i < 0) return NULL;
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mObjects.valueAt(i).object;
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpBinder::ObjectManager::detach(const void* objectID)
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mObjects.removeItem(objectID);
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpBinder::ObjectManager::kill()
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = mObjects.size();
76d4ecccfd206604a9b2d8a1220844fc2df85a5998Mark Salyzyn    ALOGV("Killing %zu objects in manager %p", N, this);
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0; i<N; i++) {
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const entry_t& e = mObjects.valueAt(i);
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (e.func != NULL) {
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mObjects.clear();
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpBinder::BpBinder(int32_t handle)
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHandle(handle)
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    , mAlive(1)
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    , mObitsSent(0)
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    , mObituaries(NULL)
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
956807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block    ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    IPCThreadState::self()->incWeakHandle(handle);
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10183c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopianbool BpBinder::isDescriptorCached() const {
10283c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian    Mutex::Autolock _l(mLock);
10383c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian    return mDescriptorCache.size() ? true : false;
10483c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian}
10583c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian
10683c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopianconst String16& BpBinder::getInterfaceDescriptor() const
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10883c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian    if (isDescriptorCached() == false) {
10983c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian        Parcel send, reply;
11083c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian        // do the IPC without a lock held.
11183c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian        status_t err = const_cast<BpBinder*>(this)->transact(
11283c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian                INTERFACE_TRANSACTION, send, &reply);
11383c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian        if (err == NO_ERROR) {
11483c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian            String16 res(reply.readString16());
11583c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian            Mutex::Autolock _l(mLock);
11683c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian            // mDescriptorCache could have been assigned while the lock was
11783c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian            // released.
11883c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian            if (mDescriptorCache.size() == 0)
11983c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian                mDescriptorCache = res;
12083c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian        }
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
122d4ecccfd206604a9b2d8a1220844fc2df85a5998Mark Salyzyn
12383c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian    // we're returning a reference to a non-static object here. Usually this
124d4ecccfd206604a9b2d8a1220844fc2df85a5998Mark Salyzyn    // is not something smart to do, however, with binder objects it is
12583c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian    // (usually) safe because they are reference-counted.
126d4ecccfd206604a9b2d8a1220844fc2df85a5998Mark Salyzyn
12783c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian    return mDescriptorCache;
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool BpBinder::isBinderAlive() const
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mAlive != 0;
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BpBinder::pingBinder()
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Parcel send;
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Parcel reply;
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = transact(PING_TRANSACTION, send, &reply);
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err != NO_ERROR) return err;
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (status_t)reply.readInt32();
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BpBinder::dump(int fd, const Vector<String16>& args)
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Parcel send;
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Parcel reply;
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    send.writeFileDescriptor(fd);
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t numArgs = args.size();
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    send.writeInt32(numArgs);
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i = 0; i < numArgs; i++) {
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        send.writeString16(args[i]);
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = transact(DUMP_TRANSACTION, send, &reply);
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BpBinder::transact(
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Once a binder has died, it will never come back to life.
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mAlive) {
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        status_t status = IPCThreadState::self()->transact(
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mHandle, code, data, reply, flags);
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (status == DEAD_OBJECT) mAlive = 0;
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return status;
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return DEAD_OBJECT;
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BpBinder::linkToDeath(
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Obituary ob;
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ob.recipient = recipient;
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ob.cookie = cookie;
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ob.flags = flags;
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOG_ALWAYS_FATAL_IF(recipient == NULL,
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        "linkToDeath(): recipient must be non-NULL");
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        AutoMutex _l(mLock);
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!mObitsSent) {
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!mObituaries) {
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mObituaries = new Vector<Obituary>;
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (!mObituaries) {
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    return NO_MEMORY;
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1936807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                getWeakRefs()->incWeak(this);
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState* self = IPCThreadState::self();
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                self->requestDeathNotification(mHandle, this);
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                self->flushCommands();
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ssize_t res = mObituaries->add(ob);
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return DEAD_OBJECT;
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BpBinder::unlinkToDeath(
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    wp<DeathRecipient>* outRecipient)
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    AutoMutex _l(mLock);
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mObitsSent) {
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return DEAD_OBJECT;
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = mObituaries ? mObituaries->size() : 0;
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0; i<N; i++) {
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Obituary& obit = mObituaries->itemAt(i);
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((obit.recipient == recipient
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    || (recipient == NULL && obit.cookie == cookie))
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                && obit.flags == flags) {
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t allFlags = 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